Updated Zorro-LAN-IDE Driver to 2.15
- Multicast fixes - new Microchip OUIs added to verification table
This commit is contained in:
@@ -23,11 +23,13 @@
|
||||
DEBUG EQU 0
|
||||
GLOBALINT_BOARD EQU 0 ;if 1, then toggle board interrupt, else ENC624 INTIE
|
||||
OPT_AVOID_DEFAULT_RESETS EQU 1 ;if 1, then check valid Microchip MAC OUI and don't reset the whole chip if the MAC address is ok
|
||||
OPT_Z2_WORDREAD EQU 1 ;read words instead of Longs on Z2 (specifically, 68030)
|
||||
|
||||
incdir src:baxnet/trunk/source/
|
||||
;Temp:Amiga/src/Zorro-LAN-IDE.git/Driver/enc624j6net/
|
||||
include "enc624j6net/registers.i"
|
||||
include "enc624j6net/macros.i"
|
||||
include "hw.i"
|
||||
|
||||
ifnd DEBUG
|
||||
DEBUG EQU 0
|
||||
@@ -129,6 +131,9 @@ ENC_BOARDID EQU 123 ;ZII-IDE-LAN-CP
|
||||
XDEF _enc624j6l_ReadPHY
|
||||
XDEF _enc624j6l_WritePHY
|
||||
|
||||
ifne OPT_Z2_WORDREAD
|
||||
XDEF _enc624j6l_Z2Mode
|
||||
endc
|
||||
|
||||
;
|
||||
; System includes
|
||||
@@ -457,7 +462,16 @@ a
|
||||
dc.b $04,$91,$62,0
|
||||
dc.b $54,$10,$EC,0
|
||||
dc.b $80,$1F,$12,0
|
||||
dc.b $D8,$80,$39,0
|
||||
dc.b $D8,$80,$39,0
|
||||
;new registrations by Microchip
|
||||
dc.b $e8,$eb,$1b,0 ; 23-Jun-2020
|
||||
dc.b $80,$34,$28,0 ; 22-Dec-2020
|
||||
dc.b $60,$8a,$10,0 ; 30-Mar-2021
|
||||
dc.b $fc,$0f,$e7,0 ; 10-Sep-2021
|
||||
dc.b $9c,$95,$6e,0 ; 21-Apr-2022
|
||||
dc.b $44,$b7,$d0,0 ; 02-Aug-2022
|
||||
dc.b $D8,$47,$8f,0 ; 13-Jan-2023
|
||||
dc.b $40,$84,$32,0 ; 30-Mar-2023
|
||||
dc.b 0,0,0,0
|
||||
|
||||
.dorst:
|
||||
@@ -657,7 +671,7 @@ _enc624j6l_Init:
|
||||
move #RXSTOP_INIT&$fffe,d0
|
||||
WRITEREG ERXTAIL,a0,d0 ;tail pointer in buffer = rx-2, wraparound
|
||||
|
||||
; ifne _OPT_FLOWCONTROL
|
||||
; ifne _OPT_FLOWCONTROL ;this is now a runtime option
|
||||
moveq #PIO_INIT_FLOW_CONTROL,d0
|
||||
and d1,d0
|
||||
beq.s .init_noflow
|
||||
@@ -809,7 +823,50 @@ _enc624j6l_SetOnline:
|
||||
|
||||
moveq #0,d0
|
||||
WRITEREG PLinkChange,a0,d0 ;no detected/acknowledged link right now, i.e. LNK and DPX bits = 0
|
||||
|
||||
|
||||
ifne 1
|
||||
moveq #48,d0 ;was: 12
|
||||
move.l d0,-(sp)
|
||||
.an_wait_loop:
|
||||
moveq #100,d0 ;
|
||||
lsl.l #5,d0 ;wait 3.2ms (0.1*32)
|
||||
bsr _enc624j6l_UMinDelay ;
|
||||
|
||||
moveq #PHSTAT1,d0 ;AUTONEG DONE, forced speeds/duplex
|
||||
bsr _enc624j6l_ReadPHY
|
||||
and.w #PHSTAT1_ANDONE,d0 ;autoneg success?
|
||||
beq.s .an_not_finished
|
||||
|
||||
bsr _enc624j6l_CheckLinkChange ;
|
||||
bra.s .an_finished
|
||||
.an_not_finished:
|
||||
subq.l #1,(sp)
|
||||
bgt.s .an_wait_loop
|
||||
.an_finished:
|
||||
addq.l #4,sp
|
||||
endc
|
||||
|
||||
ifne 0
|
||||
;---------------- until HW comes upe ----------------------------------
|
||||
;
|
||||
;wait 256 us
|
||||
;
|
||||
moveq #40,d1 ;
|
||||
.txwait:
|
||||
READREG ECON1,a0,d0
|
||||
and.w #ECON1_TXRTS,d0
|
||||
beq.s .txrdy
|
||||
;100 MBit/s frame time is max. 0.12 ms (without inter-frame spacing)
|
||||
|
||||
;WRITEDEBUG TXWait_MSG
|
||||
|
||||
;wait 5 us via CIA
|
||||
moveq #5,d0
|
||||
bsr _enc624j6l_UMinDelay
|
||||
dbf d1,.txwait ;approx. 1ms max. wait
|
||||
.txrdy:
|
||||
endc
|
||||
|
||||
;moveq #1,d0 ;already set, see above
|
||||
.err
|
||||
rts
|
||||
@@ -1073,6 +1130,7 @@ _enc624j6l_IntServer_List:
|
||||
; In: A0 = board base address
|
||||
;
|
||||
; Out: D0 <0 error
|
||||
;
|
||||
; =0 ok, no link change handled
|
||||
; >0 ok, link change handled
|
||||
;
|
||||
@@ -1080,7 +1138,7 @@ _enc624j6l_IntServer_List:
|
||||
;
|
||||
_enc624j6l_CheckLinkChange:
|
||||
move.l a0,d0
|
||||
beq.s .rts
|
||||
beq.s .err ;error: we don't have a board
|
||||
|
||||
; link change events are captured with Interrupts and stored
|
||||
; in the (custom) PLinkChange location (per board) by init and
|
||||
@@ -1145,7 +1203,8 @@ _enc624j6l_CheckLinkChange:
|
||||
moveq #0,d0
|
||||
.rts:
|
||||
rts
|
||||
|
||||
.err: moveq #HW_MAC_INVALID,d0 ;-1
|
||||
rts
|
||||
|
||||
;---------------------------------------------------------------------------------------
|
||||
;
|
||||
@@ -1272,6 +1331,305 @@ _enc624j6l_HaveRecv:
|
||||
bra.s .rts
|
||||
|
||||
|
||||
ifne OPT_Z2_WORDREAD
|
||||
;---------------------------------------------------------------------------------------
|
||||
;
|
||||
; receive single frame from HW into supplied memory buffer (Z2 Only)
|
||||
;
|
||||
; input: A0 - APTR mmapped board base address
|
||||
; A1 - APTR buffer for received frame
|
||||
; D0 - SHORT maximum size in buffer
|
||||
;
|
||||
; output: D0 <0 - error (i.e. frame too large)
|
||||
; 0 - no pending frames
|
||||
; >0 - size of received frame in buffer
|
||||
;
|
||||
; trash: -
|
||||
;
|
||||
; notes:
|
||||
;
|
||||
|
||||
|
||||
_enc624j6l_RecvFrameZ2:
|
||||
;WORD READS ONLY
|
||||
movem.l d2-d7/a1-a3,-(sp)
|
||||
move.l a0,d1
|
||||
beq .err
|
||||
|
||||
moveq #0,d0
|
||||
READREG ESTAT,a0,d2 ;number of pending frames
|
||||
move.b d2,d0 ;clear out count (ESTAT_PKTCNT7...ESTAT_PKTCNT0)
|
||||
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
|
||||
;lea (a0,d7.w),a2 ;read ptr for next packet address
|
||||
;READREG 0,a2,d0 ;next packet pointer
|
||||
|
||||
READSRAM a0,d7,d0 ;move (a0,d7.w),d0
|
||||
ifeq _OPT_BUFFER_SWAP
|
||||
rol.w #8,d0 ;swap pointer to Big Endian
|
||||
endc
|
||||
|
||||
;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
|
||||
cmp d0,d7
|
||||
bgt.s .maybewrap
|
||||
;unwrapped next packet
|
||||
move d0,d1
|
||||
bra.s .ptrcheck
|
||||
.maybewrap:
|
||||
;wrapped next packet ?
|
||||
move #RXSTOP_INIT+1-RXSTART_INIT,d1 ;unwrap distance
|
||||
add.w d0,d1 ;next pkt + unwrap distance
|
||||
.ptrcheck:
|
||||
sub.w d7,d1 ;length of pkt
|
||||
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...)
|
||||
|
||||
;------------------ check receive status vector -----------------------------
|
||||
addq.w #2,d7 ;increment pointer
|
||||
WRAPINDEX d7 ;wrap D7 if beyond buffer
|
||||
|
||||
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,d2 ;move (a0,d7.w),d0
|
||||
ifeq _OPT_BUFFER_SWAP
|
||||
rol.w #8,d2 ;swap pointer to Big Endian
|
||||
endc ;_OPT_BUFFER_SWAP
|
||||
endc ;0
|
||||
|
||||
;D1 is the distance to the next frame = stored length + recv vevtor
|
||||
subq #6+2,d1 ;STATUS VECTOR, Pointer
|
||||
move d1,d0 ;
|
||||
|
||||
subq #4,d0 ;subtract CRC length
|
||||
|
||||
addq.w #2,d7 ;increment pointer (skip status vector length field)
|
||||
WRAPINDEX d7 ;wrap D7 if beyond buffer
|
||||
|
||||
;d0.w: length (without crc)
|
||||
;d7.w: read position (beginning of frame, dest MAC)
|
||||
;a0: board I/O
|
||||
;a1: dest pointer
|
||||
move.l a1,a3
|
||||
|
||||
ifne _OPT_RECV
|
||||
move.l d7,d1 ;start
|
||||
;and.l #$FFFF,d1 ;keep only lower address
|
||||
add.w d0,d1 ;start+bytes
|
||||
bvs.s .nooptrecv ;what? beyond 16 Bit ? -> we really should consider this an error, really :-)
|
||||
cmp.w #RXSTOP_INIT,d1 ;
|
||||
bgt.s .nooptrecv ;sadly, we cannot use faster routine atm, because we have a wrap around in the SRAM buffer
|
||||
|
||||
ifne _OPT_ADR_QUIRK
|
||||
eor.w #$6000,d7
|
||||
endc ;_OPT_ADR_QUIRK
|
||||
|
||||
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
|
||||
bra.s .opt16_read
|
||||
.opt16_loop:
|
||||
move.w d3,(a1)+
|
||||
.opt16_read:
|
||||
rept 3
|
||||
move.w (a2)+,(a1)+
|
||||
move.w (a2)+,(a1)+
|
||||
endr
|
||||
move.w (a2)+,(a1)+
|
||||
move.w (a2)+,d3
|
||||
dbf d2,.opt16_loop
|
||||
move.w d3,(a1)+
|
||||
.nopt16_read:
|
||||
else ;_OPT_BUFFER_SWAP
|
||||
moveq #3,d1 ;round bytes up
|
||||
add d0,d1 ;byte count + 3
|
||||
endc ;_OPT_BUFFER_SWAP
|
||||
lsr #2,d1 ;converted to dword count = ceil(bytes/4)
|
||||
subq #1,d1 ;longwords - 1
|
||||
blt.s .end_read
|
||||
.opt_read:
|
||||
ifne _OPT_BUFFER_SWAP
|
||||
move.w (a2)+,d2 ;get current word
|
||||
rol.w #8,d2 ;swap buffer to Big Endian
|
||||
move.w d2,(a1)+
|
||||
move.w (a2)+,d2
|
||||
rol.w #8,d2 ;swap buffer to Big Endian
|
||||
move.w d2,(a1)+
|
||||
else ;_OPT_BUFFER_SWAP
|
||||
move.w (a2)+,(a1)+
|
||||
move.w (a2)+,(a1)+
|
||||
endc ;_OPT_BUFFER_SWAP
|
||||
dbf d1,.opt_read
|
||||
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
|
||||
;
|
||||
move.w #RXSTOP_INIT+1,d1 ;end address $6000
|
||||
lea (a0,d7.w),a2 ;read pointer
|
||||
sub.w d7,d1 ;minus start pointer = number of bytes until wrap
|
||||
cmp.w d0,d1 ;
|
||||
bhi.s .emergency_slow ;don`t trust anyone: if d1<0 or >total_length, then branch to slow routine
|
||||
|
||||
move d1,d2
|
||||
lsr #2,d2 ;we copy long words
|
||||
subq #1,d2 ;dbf
|
||||
blt.s .nowords_beforewrap ;
|
||||
.loop_beforewrap:
|
||||
move.w (a2)+,(a1)+
|
||||
move.w (a2)+,(a1)+
|
||||
dbf d2,.loop_beforewrap
|
||||
|
||||
.nowords_beforewrap: ;
|
||||
btst #1,d7 ;uneven longword address before wraparound ?
|
||||
beq.s .copy_afterwrap
|
||||
move.w (a2)+,(a1)+ ;copy word from uneven address
|
||||
.copy_afterwrap:
|
||||
|
||||
move #RXSTART_INIT,d7 ;wrap
|
||||
lea (a0,d7.w),a2 ;read pointer
|
||||
|
||||
move d0,d2 ;total bytes to read
|
||||
sub.w d1,d2 ;remaining=total-copied (D1=RXSTOP_INIT+1-D7)
|
||||
ble.s .end_read ;done, if zero
|
||||
|
||||
move d2,d1 ;
|
||||
lsr #2,d2 ;we copy long words
|
||||
bra.s .enter_afterwrap
|
||||
.loop_afterwrap:
|
||||
move.w (a2)+,(a1)+
|
||||
move.w (a2)+,(a1)+
|
||||
.enter_afterwrap:
|
||||
dbf d2,.loop_afterwrap
|
||||
|
||||
and.b #3,d1 ;btst #1,d1 ;1 byte or short remaining ?
|
||||
beq.s .end_read
|
||||
move.w (a2)+,(a1)+
|
||||
bra.s .end_read
|
||||
|
||||
.emergency_slow:
|
||||
endc ;_OPT_BUFFER_SWAP
|
||||
endc ;_OPT_RECV
|
||||
|
||||
;generic loop: check for position overflows with each word
|
||||
;
|
||||
;CAUTION: DWORD loop doesn`t apply here since buffer is organized
|
||||
; in multiples of two bytes, same for frame lengths and
|
||||
; possible wraparounds
|
||||
;
|
||||
moveq #1,d2 ;mask for lower bit
|
||||
move d0,d1 ;byte count
|
||||
lsr #1,d1 ;converted to word count
|
||||
and.l d0,d2 ;if lower bits are set ->
|
||||
bne.s .generic_read ;read 1 word more if impair byte/word count
|
||||
subq #1,d1 ;words - 1
|
||||
.generic_read:
|
||||
move.w (a0,d7.w),d2 ;get current word
|
||||
ifne _OPT_BUFFER_SWAP
|
||||
rol.w #8,d2 ;swap buffer to Big Endian
|
||||
endc
|
||||
move.w d2,(a1)+ ; store currend word
|
||||
addq #2,d7 ;increment position
|
||||
WRAPINDEX d7 ;wrap D7 if beyond buffer
|
||||
dbf d1,.generic_read
|
||||
|
||||
.end_read:
|
||||
;frame copied, now advance HW pointer
|
||||
READREG PNextPacket,a0,d1 ;write pointer for next packet
|
||||
cmp #RXSTART_INIT,d1
|
||||
bne.s .tail_nowrap
|
||||
move #(RXSTOP_INIT&$fffe)+2,d1
|
||||
.tail_nowrap:
|
||||
subq #2,d1
|
||||
WRITEREG ERXTAIL,a0,d1 ;tail pointer in buffer = rx-2, wraparound
|
||||
|
||||
move #ECON1_PKTDEC,d1
|
||||
SETREG ECON1,a0,d1 ;set packet decrement ("frame", actually)
|
||||
|
||||
ext.l d0
|
||||
ifne ADD_4RX
|
||||
addq.l #4,d0 ;+4 (fake CRC) for Shapeshifter, also see server.c plain copy mode
|
||||
endc
|
||||
|
||||
cmp.w #14,d0
|
||||
bge.s .rts
|
||||
|
||||
moveq #0,d0
|
||||
.rts:
|
||||
movem.l (sp)+,d2-d7/a1-a3
|
||||
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
|
||||
|
||||
moveq #ECON1_RXEN,d0 ;re-enable reception
|
||||
SETREG ECON1,a0,d0
|
||||
|
||||
moveq #0,d0
|
||||
bra.s .rts
|
||||
|
||||
|
||||
|
||||
|
||||
endc
|
||||
|
||||
;---------------------------------------------------------------------------------------
|
||||
;
|
||||
; receive single frame from HW into supplied memory buffer
|
||||
@@ -1289,10 +1647,17 @@ _enc624j6l_HaveRecv:
|
||||
; notes:
|
||||
;
|
||||
_enc624j6l_RecvFrame: ;
|
||||
ifne OPT_Z2_WORDREAD
|
||||
tst.l Z2Mode
|
||||
bne.w _enc624j6l_RecvFrameZ2
|
||||
endc
|
||||
|
||||
movem.l d2-d7/a1-a3,-(sp)
|
||||
move.l a0,d1
|
||||
beq .err
|
||||
|
||||
|
||||
|
||||
moveq #0,d0
|
||||
READREG ESTAT,a0,d2 ;number of pending frames
|
||||
move.b d2,d0 ;clear out count (ESTAT_PKTCNT7...ESTAT_PKTCNT0)
|
||||
@@ -1899,4 +2264,12 @@ _enc624j6l_UMinDelay:
|
||||
;recvcount: dc.l 0
|
||||
;recvlist: ds.w 65536
|
||||
|
||||
;separate section necessary with SAS/C
|
||||
section data,data
|
||||
|
||||
Z2Mode:
|
||||
_enc624j6l_Z2Mode:
|
||||
dc.l 0
|
||||
|
||||
|
||||
END
|
||||
|
||||
Reference in New Issue
Block a user