LAN Driver

- bugfix: wraparound aware RX routine was potentially over- or undershooting 
    by two bytes
  - slight improvement to RX loop
  - revision bump to 0.2
This commit is contained in:
HenrykRichter
2018-04-16 21:29:40 +02:00
parent 16f86601d9
commit d676378aba
4 changed files with 84 additions and 67 deletions
+33 -25
View File
@@ -1,3 +1,4 @@
;APS00000000000000000000000000000000000000000000000000000000000000000000000000000000
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
; | Lowlevel Access to memory mapped ENC624J600 in PSP mode | ; | Lowlevel Access to memory mapped ENC624J600 in PSP mode |
; | Henryk Richter <henryk.richter@gmx.net> | ; | Henryk Richter <henryk.richter@gmx.net> |
@@ -18,6 +19,7 @@
; - _enc624j6l_RXReset -> won't recover from totally unresponsive chip (but exits gracefully) ; - _enc624j6l_RXReset -> won't recover from totally unresponsive chip (but exits gracefully)
; - RXSTART_INIT = $0c00 -> currently $2000 due to location bug ; - RXSTART_INIT = $0c00 -> currently $2000 due to location bug
incdir Temp:Amiga/src/Zorro-LAN-IDE.git/Driver/enc624j6net/
include "enc624j6net/registers.i" include "enc624j6net/registers.i"
include "enc624j6net/macros.i" include "enc624j6net/macros.i"
@@ -809,7 +811,7 @@ _enc624j6l_IntServer:
moveq #EIR_PKTIF,d1 moveq #EIR_PKTIF,d1
READREG EIR,a1,d0 ;get interrupt status reg READREG EIR,a1,d0 ;get interrupt status reg
and d1,d0 and d1,d0
beq.s .rts ;exit quickly when no packet pending beq.s .rts ;exit quickly when no packet pending
;CLRREG EIR,a1,d1 ;clear interrupt bit ;CLRREG EIR,a1,d1 ;clear interrupt bit
@@ -821,17 +823,17 @@ _enc624j6l_IntServer:
move #EIE_INTIE,D0 ;disable board interrupt until someone enables it again move #EIE_INTIE,D0 ;disable board interrupt until someone enables it again
CLRREG EIE,A1,d0 CLRREG EIE,A1,d0
READREG PSigTask,a1,d0 ;upper two bytes READREG PSigTask,a1,d0 ;upper two bytes
swap d0 ; swap d0 ;
READREG PSigTask+2,a1,d0 ;lower two bytes READREG PSigTask+2,a1,d0 ;lower two bytes
tst.l d0 ; no task ? tst.l d0 ; no task ?
beq.s .rts beq.s .rts
move.l d0,a0 ; signaled task move.l d0,a0 ; signaled task
moveq #0,d0 moveq #0,d0
READREG PSigBit,a1,d1 ;get signal bit READREG PSigBit,a1,d1 ;get signal bit
bset d1,d0 ;signal mask bset d1,d0 ;signal mask
move.l a0,a1 ;task move.l a0,a1 ;task
move.l 4.w,a6 move.l 4.w,a6
jsr _LVOSignal(a6) jsr _LVOSignal(a6)
@@ -1018,10 +1020,12 @@ _enc624j6l_RecvFrame: ;
move d1,d0 ; move d1,d0 ;
else else
cmp #2,d0 cmp #2,d0
blt .recv_err ;can't be: SRC MAC 6 DST MAC 6 LEN/TYPE 2 CRC 4 (discounting variable data) blt .recv_err ;can't be: SRC MAC 6 DST MAC 6 LEN/TYPE 2 CRC 4 (discounting variable data)
cmp #MAX_FRAMELEN,d0 cmp #MAX_FRAMELEN,d0
bgt .recv_err bgt .recv_err
endc endc
subq #4,d0 ;subtract CRC length subq #4,d0 ;subtract CRC length
@@ -1037,19 +1041,20 @@ _enc624j6l_RecvFrame: ;
ifne _OPT_RECV ifne _OPT_RECV
move.l d7,d1 ;start move.l d7,d1 ;start
and.l #$FFFF,d1 ;keep only lower address ;and.l #$FFFF,d1 ;keep only lower address
add.l d0,d1 ;start+bytes add.w d0,d1 ;start+bytes
cmp.l #RXSTOP_INIT,d1 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 bgt.s .nooptrecv ;sadly, we cannot use faster routine atm, because we have a wrap around in the SRAM buffer
ifne _OPT_ADR_QUIRK ifne _OPT_ADR_QUIRK
eor.w #$6000,d7 eor.w #$6000,d7
endc endc
lea (a0,d7.w),a2 ;read pointer lea (a0,d7.w),a2 ;read pointer
move d0,d1 ;byte count moveq #3,d1 ;round bytes up
lsr #2,d1 ;converted to dword count add d0,d1 ;byte count + 3
bcs.s .opt_read ;read 1 byte more if impair byte count lsr #2,d1 ;converted to dword count = ceil(bytes/4)
subq #1,d1 ;words - 1 subq #1,d1 ;longwords - 1
.opt_read: .opt_read:
ifne _OPT_BUFFER_SWAP ifne _OPT_BUFFER_SWAP
move.l (a2)+,d2 ;get current word move.l (a2)+,d2 ;get current word
@@ -1066,22 +1071,25 @@ _enc624j6l_RecvFrame: ;
.nooptrecv: .nooptrecv:
endc ;_OPT_RECV endc ;_OPT_RECV
;generic loop: check for position overflows with each dword ;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 move d0,d1 ;byte count
lsr #2,d1 ;converted to dword count lsr #1,d1 ;converted to word count
bcs.s .generic_read ;read 1 byte more if impair byte 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 subq #1,d1 ;words - 1
.generic_read: .generic_read:
READSRAM_LONG a0,d7,d2 ;get current dword move.w (a0,d7.w),d2 ;get current word
;move.l (a0,d7.w),d2 ;get current dword
ifne _OPT_BUFFER_SWAP ifne _OPT_BUFFER_SWAP
rol.w #8,d2 ;swap buffer to Big Endian rol.w #8,d2 ;swap buffer to Big Endian
SWAP D2
rol.w #8,d2 ;swap buffer to Big Endian
SWAP D2
endc endc
move.l d2,(a1)+ ; store currend dword move.w d2,(a1)+ ; store currend word
addq #4,d7 ;increment position addq #2,d7 ;increment position
WRAPINDEX d7 ;wrap D7 if beyond buffer WRAPINDEX d7 ;wrap D7 if beyond buffer
dbf d1,.generic_read dbf d1,.generic_read
+4
View File
@@ -241,6 +241,7 @@ GLOBAL REGARGS void hw_config_dump(struct PLIPBase *pb)
GLOBAL REGARGS BOOL hw_init(struct PLIPBase *pb) GLOBAL REGARGS BOOL hw_init(struct PLIPBase *pb)
{ {
struct HWBase *hwb = &pb->pb_HWBase; struct HWBase *hwb = &pb->pb_HWBase;
/*ULONG tst;*/
BOOL rc = FALSE; BOOL rc = FALSE;
@@ -253,10 +254,13 @@ GLOBAL REGARGS BOOL hw_init(struct PLIPBase *pb)
hwb->hwb_Interrupt.is_Data = (0); /* prepare interrupt */ hwb->hwb_Interrupt.is_Data = (0); /* prepare interrupt */
hwb->hwb_Interrupt.is_Code = (0); hwb->hwb_Interrupt.is_Code = (0);
/*tst = AllocSignal(-1);*/
/* interesting: we get CTRL-F by default. Indidentally the same signal used for the write queue */
if ((hwb->hwb_IntSig = AllocSignal(-1)) != -1) if ((hwb->hwb_IntSig = AllocSignal(-1)) != -1)
{ {
hwb->hwb_IntSigMask = 1L << hwb->hwb_IntSig; hwb->hwb_IntSigMask = 1L << hwb->hwb_IntSig;
d2(("int sigmask=%08lx\n",hwb->hwb_IntSigMask)); d2(("int sigmask=%08lx\n",hwb->hwb_IntSigMask));
/*FreeSignal(tst);*/
if ((hwb->hwb_TimeoutPort = CreateMsgPort())) if ((hwb->hwb_TimeoutPort = CreateMsgPort()))
{ {
+44 -39
View File
@@ -356,7 +356,9 @@ PRIVATE REGARGS BOOL read_frame(struct IOSana2Req *req, struct HWFrame *frame)
BOOL rv,ok; BOOL rv,ok;
struct HWFrame *frame = pb->pb_Frame; struct HWFrame *frame = pb->pb_Frame;
while(hw_recv_pending(pb)){ /* while(hw_recv_pending(pb)){*/
while(1){
/* if(1){ */
d8(("+hw_recv\n")); d8(("+hw_recv\n"));
rv = hw_recv_frame(pb, frame); rv = hw_recv_frame(pb, frame);
d8(("-hw_recv\n")); d8(("-hw_recv\n"));
@@ -443,11 +445,15 @@ PRIVATE REGARGS BOOL read_frame(struct IOSana2Req *req, struct HWFrame *frame)
} }
else else
{ {
#if 1
break;
#else
d(("Error receiving (%ld. len=%ld)\n", rv, frame->hwf_Size)); d(("Error receiving (%ld. len=%ld)\n", rv, frame->hwf_Size));
/* something went wrong during receipt */ /* something went wrong during receipt */
DoEvent(pb, S2EVENT_HARDWARE | S2EVENT_ERROR | S2EVENT_RX); DoEvent(pb, S2EVENT_HARDWARE | S2EVENT_ERROR | S2EVENT_RX);
got = NULL; got = NULL;
pb->pb_DevStats.BadData++; pb->pb_DevStats.BadData++;
#endif
} }
} }
} }
@@ -695,56 +701,55 @@ PRIVATE REGARGS BOOL read_frame(struct IOSana2Req *req, struct HWFrame *frame)
wmask = SIGBREAKF_CTRL_F | SIGBREAKF_CTRL_C | portsigmask | recvsigmask; wmask = SIGBREAKF_CTRL_F | SIGBREAKF_CTRL_C | portsigmask | recvsigmask;
/* main loop of server task */ /* main loop of server task */
d(("--- server main loop: %08lx ---\n", wmask)); d(("--- server main loop: %08lx ---\n", wmask));
for(running=TRUE;running;) for(running=TRUE;running;)
{ {
d4(("** wmask is 0x%08lx\n", wmask)); d4(("** wmask is 0x%08lx\n", wmask));
/* send packets if any */ /* send packets if any */
d2(("*+ do_write\n")); d2(("*+ do_write\n"));
wr = (struct IOSana2Req *)pb->pb_WriteList.lh_Head; wr = (struct IOSana2Req *)pb->pb_WriteList.lh_Head;
if( wr->ios2_Req.io_Message.mn_Node.ln_Succ ) if( wr->ios2_Req.io_Message.mn_Node.ln_Succ )
{ {
dowritereqs(pb); dowritereqs(pb);
} }
d2(("*- do_write\n")); d2(("*- do_write\n"));
/* if no recv is pending then wait for incoming signals */ /* if no recv is pending then wait for incoming signals */
haverec = hw_recv_pending(pb); haverec = hw_recv_pending(pb);
recv = 0; recv = 0;
if( !haverec ) if( !haverec )
{ {
d2(("**> wait\n")); d2(("**> wait\n"));
hw_enable_global_int(pb); hw_enable_global_int(pb);
recv = Wait(wmask); recv = Wait(wmask);
d2(("**> wait: got 0x%08lx\n", recv)); d2(("**> wait: got 0x%08lx\n", recv));
} /*haverec = hw_recv_pending(pb);*/
/*hw_disable_global_int(pb);*/ }
/* accept pending receive and start reading */ /* accept pending receive and start reading */
d2(("*+ do_read\n")); d2(("*+ do_read\n"));
doreadreqs(pb); doreadreqs(pb);
d2(("*- do_read\n")); d2(("*- do_read\n"));
if( recv & specialmask )
if( recv & specialmask ) {
{ /* handle SANA-II send requests */
/* handle SANA-II send requests */ if (recv & portsigmask)
if (recv & portsigmask) {
{ d(("SANA-II request(s)\n"));
d(("SANA-II request(s)\n")); dos2reqs(pb);
dos2reqs(pb); recv &= ~portsigmask;
recv &= ~portsigmask; }
} /* stop server task */
/* stop server task */ if (recv & SIGBREAKF_CTRL_C)
if (recv & SIGBREAKF_CTRL_C) {
{ d(("received break signal\n"));
d(("received break signal\n")); running = FALSE;
running = FALSE; }
} }
} } /*main loop of server task*/
} /*main loop of server task*/
} }
else else
d(("init() failed\n")); d(("init() failed\n"));
+2 -2
View File
@@ -8,9 +8,9 @@
# based on Magplip build file # based on Magplip build file
##################################################################### #####################################################################
# #
DEVICE_DATE = 18.12.2017 DEVICE_DATE = 16.04.2018
DEVICE_VERSION = 0 DEVICE_VERSION = 0
DEVICE_REVISION = 1 DEVICE_REVISION = 2
# see below for EXTRAOBJ, disable for plipbox, enable for sdnet/enc624j6net # see below for EXTRAOBJ, disable for plipbox, enable for sdnet/enc624j6net
HWSRCDIR = enc624j6net HWSRCDIR = enc624j6net