From 13c4b7f8e6b0c1ae3f7a3888c78b1cc7d982ead2 Mon Sep 17 00:00:00 2001 From: HenrykRichter Date: Tue, 9 Jan 2018 21:40:50 +0100 Subject: [PATCH] ENC624J6Net - changed interrupt usage for Int2 instead of Int6 (after discussion with Matze about "best" approach) - see HW_INTSOURCE in hw.c for the active interrupt source - this build reflects changed word handling in CPLD code, now all addresses below $6000 are presented as Big Endian words, such that copies of the frames can be done with fast instructions like movem --- Driver/enc624j6net/README.txt | 6 +- .../enc624j6net/build/enc624j6net.device.020 | Bin 11568 -> 11620 bytes Driver/enc624j6net/device.c | 55 +++++++++++++++++ Driver/enc624j6net/enc624j6net/enc624j6l.asm | 57 ++++++++++++++---- Driver/enc624j6net/enc624j6net/hw.c | 18 ++++-- Driver/enc624j6net/enc624j6net/hwbase.h | 11 ++-- Driver/enc624j6net/server.c | 8 +-- Driver/enc624j6net/smakefile | 5 +- 8 files changed, 129 insertions(+), 31 deletions(-) diff --git a/Driver/enc624j6net/README.txt b/Driver/enc624j6net/README.txt index 73f5feb..04f9b55 100644 --- a/Driver/enc624j6net/README.txt +++ b/Driver/enc624j6net/README.txt @@ -8,10 +8,10 @@ author: Henryk Richter Release Notes: -------------- -- goes along with 21 December 2017 CPLD build, where interrupts are extended +- goes along with 27 December 2017 CPLD build, where interrupts are extended - older CPLD builds will lock up Amiga at first interrupt - provisions for swapped address lines 12/13 are in the code -- board requires Int6 to be soldered (NOT Int2) +- board requires Int2 to be soldered (NOT Int6) Installation: ------------- @@ -32,8 +32,6 @@ as argument will then activate the driver for RoadShow. Technical notes: ---------------- -(IMPORTANT: not _yet_ true for current CPLD build) - Matze's card does selective byte swapping for different areas of the chip within the CPLD. This step enables Big Endian reads/writes to the hardware registers. Since the SRAM would be byte-swapped as well, the latest (WIP) version of the CPLD presents diff --git a/Driver/enc624j6net/build/enc624j6net.device.020 b/Driver/enc624j6net/build/enc624j6net.device.020 index b643b05490a22fcc918b4a3a5975f7d6c15fe96b..78792f396b500d20a31e5d62fc069a5f0e9cc441 100755 GIT binary patch delta 1305 zcmZ{kUrf_i6vxl~QK2m@e@dZ+w&v%rr4%Vr&=40J{6TTF1zQ!eRhD4O)E`m6jyc&# zQ*qgY4{lM9F~%&!_{6f!kTfI9qNHORVTQQIG{hK!(U8hA(~&JPtYffK?ZaO7@X7t& zd%pMFd(XYOQ@ty_mv!n@0H_7X`xQXBdd2b%dvs;|Pd1HbS*<^@BLc8(iA%ax;S%o& z!OndC3}_P@a5Dt8nVg;^ozCfL($8}GN79Qq{gCwi*bDYIV_mqK_a%E7yC$pV*yY%F z`TH45#xey8R+a<}Upi7Xb>W24Jj(i^giBzB;wQ%AlET0Saa~c(Qn+3DDI1A>rL=Gu zSIID;Qp!&ZzuVlj=TtK;sfKFpZ+7|LcKLlhNBmt4-Eh?Je$KeCEXv|Gw%*_dxfi7N z5U9`Laka$W!Uc6FdyM*`YPNtaMWbv6r;ARr1PaCVg|~y^k*}eLAL16Uw|F-@j-M4j zS1bsfQ3yeyfYFlo7>8>mL+l#%l{Rxq4zHK)V={bL>S2p$)Eup`xt})*w5-;Z$>>uji6DS(ZJ*gR+C=3zAY0?E|pacjq4;&6U$CP3X{m!&Wh+ zZDix9FE_FNSabP#P91Ok4IF~oJ_LKic{rKmk0dXHj-KMf-xP~E{kz22rN z3HVhVTbn2OhB_GG4+@fS4rhpDQ1^>DzS-H7#A5EQe>8~lwg+PcH6>xm6~AMgX*SP+y~=`Coj zo}F&mDkr$!hAD%!!lbf~!DPNYRVMTJ1u6f~Uo>FGQ^va8bBFJ5rO6l!fnvlvJ_KN=yxVES7iNv( z`3X|(uB_kUaBfSJD;S$Mjuy~qMT@Td;%k$`Sp;NGJDiMK9JE-iVR^h&(mR~ve4`i* zhh-EN9Zndhb~q@{sdQ}8GQpHj15=S>Tm1lO^jUSSi;ZI8T2IGJWV#lpR5E zIKq%^p9bQQbvOwy75HBV-nLfn*Js@a*22&PE1nZvcdPLD@XuQtL2DB{d)3dz_vEtv zceSQj@~xn%rh`pjPt64^h9NBZu8ULZXZSZDt-roh#hZ`pF-W^4|}`U2DO?=uz(L=r?S zEd(-N+M}Gjc2=C-%i1B8Tf_{}&nyv_L@L&V+oBxy1doV6XD0(=Vl9_c?P#uOG&{_t zB^S?NIH?oe5+yr>K8c4_;44WjdxM7L95#>5$-V3@K1n{$REs=$ycu z<$h#b7hXs^Dw;j@ylQB92eddsqY=B{Ddvl~5C+qtC4|#Xr_X!D8lkWQ${iE`IcRMn z?ZTr~{yqB*cjZPZ-H?8meGqV@U*#k>&3}MFV=e52a<2rRW?B+tmWbp6X|2MR{g^)w zJ#I)EEGd8<{`HVa{YRxfkno2(OT2#b{^ED2kc zMQj9zlozGrFz4ZXa{D;Ucw!SD0iaS|+ z0`Z`Ag~@fcd@CK1(^%;;`*{;R*p28Viu-U;Wynx3dH{AU5tiuHQqw}&K>+nUD%H9S zb*Qi(RtJFZhp-zGTGOIa8`!KiC8;<4*F5p{|Bz!7N7V(#9yI*Aw?Tm}H;CHp{!V~G z%6o)74lgqbS4T-zS)%b<22(3H)Tc0_)mQ#!vd%_SylqW`(ZUQgFqWngm!7 zzNne<#r;kG5RU28qM&aZ&H>zS!S8gLxUS2oR*P#~P`%}aQg~@Q%Qc$IlrNm6KQ;Wa zx9!ru^F?FI3|@%ZrkWSdSzp_3ckHq+$lgZ2#QNMCHi5Tt-;-P_hgKmhGz!#*4qVPX zqFB4K_LcR0kC-B62zoAg(d?-J@@DiG7SJzYK70~i7xw=T;X;cz diff --git a/Driver/enc624j6net/device.c b/Driver/enc624j6net/device.c index c115ce1..3003959 100755 --- a/Driver/enc624j6net/device.c +++ b/Driver/enc624j6net/device.c @@ -79,6 +79,15 @@ #include "enc624j6l.h" /* for MAC retrieval */ #endif +#ifdef DIRECT_WRITE +typedef enum { AW_OK, AW_BUFFER_ERROR, AW_ERROR } AW_RESULT; +PUBLIC REGARGS VOID DoEvent(BASEPTR, long event); +PUBLIC REGARGS AW_RESULT write_frame(BASEPTR, struct IOSana2Req *ios2); +#ifndef __HW_H +#include "hw.h" +#endif +#endif + #define INVALID_SDNET_UNIT 0x33 /* used by both sdnet and encnet */ /*E*/ @@ -723,9 +732,55 @@ PRIVATE APTR pb_AllocExpansion( ULONG portid, BASEPTR ) ios2->ios2_Req.io_Flags &= ~SANA2IOF_QUICK; ios2->ios2_Req.io_Error = 0; ObtainSemaphore(&pb->pb_WriteListSem); +#ifdef DIRECT_WRITE + { + AW_RESULT code; + struct IOSana2Req *currentwrite = (struct IOSana2Req*)ios2; + + code = write_frame(pb, ios2); + if (code == AW_BUFFER_ERROR) /* BufferManagement callback error */ + { + d(("buffer error\n")); + DoEvent(pb, S2EVENT_ERROR | S2EVENT_BUFF | S2EVENT_SOFTWARE); + pb->pb_SpecialStats[S2SS_TXERRORS].Count++; + d(("pb->pb_SpecialStats[S2SS_TXERRORS].Count = %ld\n",pb->pb_SpecialStats[S2SS_TXERRORS].Count)); + currentwrite->ios2_Req.io_Error = S2ERR_SOFTWARE; + currentwrite->ios2_WireError = S2WERR_BUFF_ERROR; + Remove((struct Node*)currentwrite); + DevTermIO(pb, currentwrite); + } + else if (code == AW_ERROR) + { + /* + ** this is a real line error, upper levels (e.g. Internet TCP) have + ** to care for reliability! + */ + d(("error while transmitting packet\n")); + DoEvent(pb, S2EVENT_ERROR | S2EVENT_TX | S2EVENT_HARDWARE); + pb->pb_SpecialStats[S2SS_TXERRORS].Count++; + d(("pb->pb_SpecialStats[S2SS_TXERRORS].Count = %ld\n",pb->pb_SpecialStats[S2SS_TXERRORS].Count)); + currentwrite->ios2_Req.io_Error = S2ERR_TX_FAILURE; + currentwrite->ios2_WireError = S2WERR_GENERIC_ERROR; + Remove((struct Node*)currentwrite); + DevTermIO(pb, currentwrite); + } + else /*if (code == AW_OK)*/ /* well done! */ + { + d(("packet transmitted successfully\n")); + pb->pb_DevStats.PacketsSent++; + dotracktype(pb, (ULONG) pb->pb_Frame->hwf_Type, 1, 0, currentwrite->ios2_DataLength, 0, 0); + currentwrite->ios2_Req.io_Error = S2ERR_NO_ERROR; + currentwrite->ios2_WireError = S2WERR_GENERIC_ERROR; + Remove((struct Node*)currentwrite); + DevTermIO(pb, currentwrite); + } + } + ReleaseSemaphore(&pb->pb_WriteListSem); +#else AddTail((struct List*)&pb->pb_WriteList, (struct Node*)ios2); ReleaseSemaphore(&pb->pb_WriteListSem); Signal((struct Task*)pb->pb_Server, SIGBREAKF_CTRL_F); +#endif ios2 = NULL; } break; diff --git a/Driver/enc624j6net/enc624j6net/enc624j6l.asm b/Driver/enc624j6net/enc624j6net/enc624j6l.asm index b380f0c..2b91f6f 100755 --- a/Driver/enc624j6net/enc624j6net/enc624j6l.asm +++ b/Driver/enc624j6net/enc624j6net/enc624j6l.asm @@ -30,10 +30,10 @@ DEBUG EQU 1 ; ;------------------ options, some depend on hardware (CPLD) configuration ------------------------- -_OPT_BUFFER_SWAP EQU 1 ;perform byte swap on buffer ops (1) or assume native endian (0) +_OPT_BUFFER_SWAP EQU 0 ;perform byte swap on buffer ops (1) or assume native endian (0) _OPT_REG_SWAP EQU 0 ;perform byte swap on register ops (1) or assume native endian (0) _OPT_ADR_QUIRK EQU 1 ;address lines 12/13 are swapped (1) or linear addressing (0) -_OPT_FLOWCONTROL EQU 1 ;perform flow control on RX (1) or not (0) +_OPT_FLOWCONTROL EQU 0 ;perform flow control on RX (1) or not (0) _OPT_RECV EQU 1 ;faster recv (1) or generic (0) ; @@ -65,6 +65,15 @@ PSwapTX EQU $600 ;swap between two TX buffers (one active, one activated after ; ; +;------------- driver init flags ----------------------------------- +PIO_INIT_FULL_DUPLEX EQU 1 +PIO_INIT_LOOP_BACK EQU 2 +PIO_INIT_BROAD_CAST EQU 4 +PIO_INIT_FLOW_CONTROL EQU 8 +PIO_INIT_MULTI_CAST EQU 16 +PIO_INIT_PROMISC EQU 32 + + ifne DEBUG ; @@ -1179,6 +1188,7 @@ _enc624j6l_SetMAC: ;set user defined MAC address ; testing with low turnaround time. ; ; In: A0 - Board base address +; D1 - flags ; ; Out: ; D0 <= 0 - failure @@ -1205,9 +1215,9 @@ _enc624j6l_Init: ;33.333Mhz clock out frequency (see defines above) move.w #CLOCK_DEF_CLR,d0 ;clr mask - move.w #CLOCK_DEF_SET,d1 ;set mask CLRREG ECON2,a0,d0 - SETREG ECON2,a0,d1 + move.w #CLOCK_DEF_SET,d0 ;set mask + SETREG ECON2,a0,d0 ; disable crypto engine and all interrupts move #EIR_CRYPTEN|EIR_MODEXIF|EIR_HASHIF|EIR_AESIF|EIR_LINKIF|EIR_PRDYIF|EIR_PKTIF|EIR_DMAIF|EIR_TXIF|EIR_TXABTIF|EIR_RXABTIF|EIR_PCFULIF,d0 @@ -1225,17 +1235,24 @@ _enc624j6l_Init: move #RXSTOP_INIT&$fffe,d0 WRITEREG ERXTAIL,a0,d0 ;tail pointer in buffer = rx-2, wraparound - ifne _OPT_FLOWCONTROL +; ifne _OPT_FLOWCONTROL + moveq #PIO_INIT_FLOW_CONTROL,d0 + and d1,d0 + beq.s .init_noflow + move #(128<<8)|(32),d0 ;128*96=12288 high water mark, 32*96=3072 low water mark WRITEREG ERXWM,a0,d0 moveq #MACON1_RXPAUS,d0 SETREG MACON1,a0,d0 move #ECON2_AUTOFC,d0 SETREG ECON2,a0,d0 - else + bra.s .init_flowdone +; else +.init_noflow: move #ECON2_AUTOFC,d0 CLRREG ECON2,a0,d0 ;disable automatic flow control - endc +.init_flowdone: +; endc ;--------------- TX configuration ----------------------- @@ -1595,7 +1612,12 @@ _enc624j6l_RecvFrame: ; 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 @@ -1629,6 +1651,9 @@ _enc624j6l_RecvFrame: ; ;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) bne .recv_err ;receive buffer is wrong -> re-initialize @@ -1638,6 +1663,9 @@ _enc624j6l_RecvFrame: ; ;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 + ifeq _OPT_BUFFER_SWAP + rol.w #8,d0 ;swap pointer to Big Endian + endc ifne 1 ;D1 is the distance to the next frame = stored length + recv vevtor @@ -1676,15 +1704,20 @@ _enc624j6l_RecvFrame: ; endc lea (a0,d7.w),a2 ;read pointer move d0,d1 ;byte count - lsr #1,d1 ;converted to word count + lsr #2,d1 ;converted to dword count bcs.s .opt_read ;read 1 byte more if impair byte count subq #1,d1 ;words - 1 .opt_read: - move (a2)+,d2 ;get current word - ifne _OPT_BUFFER_SWAP + ifne _OPT_BUFFER_SWAP + move.w (a2)+,d2 ;get current word rol.w #8,d2 ;swap buffer to Big Endian - endc - move d2,(a1)+ + move.w d2,(a1)+ + move.w (a2)+,d2 ;get current word + rol.w #8,d2 ;swap buffer to Big Endian + move.w d2,(a1)+ + else + move.l (a2)+,(a1)+ + endc dbf d1,.opt_read bra.s .end_read .nooptrecv: diff --git a/Driver/enc624j6net/enc624j6net/hw.c b/Driver/enc624j6net/enc624j6net/hw.c index 0c62d09..8adec66 100755 --- a/Driver/enc624j6net/enc624j6net/hw.c +++ b/Driver/enc624j6net/enc624j6net/hw.c @@ -90,8 +90,8 @@ #define BOARD hwb->hwb_boards[0] /* interrupt (choice here is INTB_EXTER or INTB_PORTS, depending on solder blob */ -#define HW_INTSOURCE INTB_EXTER -/*#define HW_INTSOURCE INTB_PORTS*/ +/*#define HW_INTSOURCE INTB_EXTER */ /* Int 6 */ +#define HW_INTSOURCE INTB_PORTS /* Int 2 */ #endif @@ -193,6 +193,7 @@ GLOBAL REGARGS void hw_config_init(struct PLIPBase *pb) hwb->hwb_fullduplex = 0; hwb->hwb_spispeed = 1; /* optimistic default */ hwb->hwb_multicast = 0; + hwb->hwb_flowcontrol= 0; /* no flow control by default */ } @@ -216,6 +217,10 @@ GLOBAL REGARGS void hw_config_update(struct PLIPBase *pb, struct TemplateConfig { hwb->hwb_multicast = 1; } + if( args->flowcontrol ) + { + hwb->hwb_flowcontrol = 1; + } } @@ -354,13 +359,14 @@ GLOBAL REGARGS BOOL hw_attach(struct PLIPBase *pb) flags = PIO_INIT_BROAD_CAST; if( hwb->hwb_multicast ) - flags |= PIO_INIT_MULTI_CAST; - + flags |= PIO_INIT_MULTI_CAST; if( hwb->hwb_fullduplex ) - flags |= PIO_INIT_FULL_DUPLEX; + flags |= PIO_INIT_FULL_DUPLEX; + if( hwb->hwb_flowcontrol ) + flags |= PIO_INIT_FLOW_CONTROL; #ifdef PROTO_ENC624NET if( enc624j6l_Init( BOARD, (unsigned long)flags ) <= 0 ) - rc = FALSE; /* ERROR IN CASE OF DEVICE NOT FOUND */ + rc = FALSE; /* ERROR IN CASE OF DEVICE NOT FOUND */ #else if( enc28j60_init( pb->pb_CfgAddr, flags ) != PIO_OK ) rc = FALSE; /* ERROR IN CASE OF DEVICE NOT FOUND */ diff --git a/Driver/enc624j6net/enc624j6net/hwbase.h b/Driver/enc624j6net/enc624j6net/hwbase.h index 74970cb..c3c8b42 100644 --- a/Driver/enc624j6net/enc624j6net/hwbase.h +++ b/Driver/enc624j6net/enc624j6net/hwbase.h @@ -39,9 +39,11 @@ struct HWBase /* config options */ ULONG hwb_timervalue; /* timer speed */ - ULONG hwb_fullduplex; /* full duplex */ + UBYTE hwb_fullduplex; /* full duplex */ + UBYTE hwb_flowcontrol; /* flow control enable (1/0) */ + UBYTE hwb_multicast; /* multicast enable */ + UBYTE hwb_free_unused1; ULONG hwb_spispeed; /* SPI speed */ - ULONG hwb_multicast; /* multicast enable */ }; #define HWB_RECV_PENDING 0 @@ -57,8 +59,8 @@ struct HWBase /* ----- config ----- */ -#define CONFIGFILE "ENV:SANA2/sdnet.config" -#define TEMPLATE "TIMER/K/N,FULLDUPLEX/S,SPISPEED/K/N,MULTICAST/S" +#define CONFIGFILE "ENV:SANA2/enc624j6net.config" +#define TEMPLATE "TIMER/K/N,FULLDUPLEX/S,SPISPEED/K/N,MULTICAST/S,FLOWCONTROL/S" /* structure to be filled by ReadArgs template */ struct TemplateConfig @@ -68,6 +70,7 @@ struct TemplateConfig ULONG fullduplex; ULONG *spispeed; ULONG multicast; + ULONG flowcontrol; }; #endif diff --git a/Driver/enc624j6net/server.c b/Driver/enc624j6net/server.c index ec0f62d..672f76d 100755 --- a/Driver/enc624j6net/server.c +++ b/Driver/enc624j6net/server.c @@ -65,12 +65,12 @@ PUBLIC VOID SAVEDS ServerTask(void); /*E*/ /*F*/ /* private */ PRIVATE struct PLIPBase *startup(void); -PRIVATE REGARGS VOID DoEvent(BASEPTR, long event); +PUBLIC REGARGS VOID DoEvent(BASEPTR, long event); PRIVATE VOID readargs(BASEPTR); PRIVATE BOOL init(BASEPTR); PRIVATE REGARGS BOOL goonline(BASEPTR); PRIVATE REGARGS VOID gooffline(BASEPTR); -PRIVATE REGARGS AW_RESULT write_frame(BASEPTR, struct IOSana2Req *ios2); +PUBLIC REGARGS AW_RESULT write_frame(BASEPTR, struct IOSana2Req *ios2); PRIVATE REGARGS VOID dowritereqs(BASEPTR); PRIVATE REGARGS VOID doreadreqs(BASEPTR); PRIVATE REGARGS VOID dos2reqs(BASEPTR); @@ -161,7 +161,7 @@ PRIVATE REGARGS VOID dos2reqs(BASEPTR); /* ** SANA-2 Event management */ -/*F*/ PRIVATE REGARGS VOID DoEvent(BASEPTR, long event) +/*F*/ PUBLIC REGARGS VOID DoEvent(BASEPTR, long event) { struct IOSana2Req *ior, *ior2; @@ -187,7 +187,7 @@ PRIVATE REGARGS VOID dos2reqs(BASEPTR); /* ** writing packets */ -/*F*/ PRIVATE REGARGS AW_RESULT write_frame(BASEPTR, struct IOSana2Req *ios2) +/*F*/ PUBLIC REGARGS AW_RESULT write_frame(BASEPTR, struct IOSana2Req *ios2) { AW_RESULT rc; struct HWFrame *frame = pb->pb_Frame; diff --git a/Driver/enc624j6net/smakefile b/Driver/enc624j6net/smakefile index 56e3061..205abf1 100644 --- a/Driver/enc624j6net/smakefile +++ b/Driver/enc624j6net/smakefile @@ -15,7 +15,10 @@ DEVICE_REVISION = 1 # see below for EXTRAOBJ, disable for plipbox, enable for sdnet/enc624j6net HWSRCDIR = enc624j6net DEVICE_NAME = enc624j6net -DEFS = DEFINE PROTO_ENC624NET=1 +DEFS = DEFINE PROTO_ENC624NET=1 + +# quick hack/test to write directly - didn't work out for me +#DEFINE DIRECT_WRITE=1 ##################################################################### #