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 b643b05..78792f3 100755 Binary files a/Driver/enc624j6net/build/enc624j6net.device.020 and b/Driver/enc624j6net/build/enc624j6net.device.020 differ 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 ##################################################################### #