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
This commit is contained in:
HenrykRichter
2018-01-09 21:40:50 +01:00
parent dde9bf1d4e
commit 13c4b7f8e6
8 changed files with 129 additions and 31 deletions
+2 -4
View File
@@ -8,10 +8,10 @@ author: Henryk Richter <henryk.richter@gmx.net>
Release Notes: 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 - older CPLD builds will lock up Amiga at first interrupt
- provisions for swapped address lines 12/13 are in the code - 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: Installation:
------------- -------------
@@ -32,8 +32,6 @@ as argument will then activate the driver for RoadShow.
Technical notes: Technical notes:
---------------- ----------------
(IMPORTANT: not _yet_ true for current CPLD build)
Matze's card does selective byte swapping for different areas of the chip within 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 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 the SRAM would be byte-swapped as well, the latest (WIP) version of the CPLD presents
Binary file not shown.
+55
View File
@@ -79,6 +79,15 @@
#include "enc624j6l.h" /* for MAC retrieval */ #include "enc624j6l.h" /* for MAC retrieval */
#endif #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 */ #define INVALID_SDNET_UNIT 0x33 /* used by both sdnet and encnet */
/*E*/ /*E*/
@@ -723,9 +732,55 @@ PRIVATE APTR pb_AllocExpansion( ULONG portid, BASEPTR )
ios2->ios2_Req.io_Flags &= ~SANA2IOF_QUICK; ios2->ios2_Req.io_Flags &= ~SANA2IOF_QUICK;
ios2->ios2_Req.io_Error = 0; ios2->ios2_Req.io_Error = 0;
ObtainSemaphore(&pb->pb_WriteListSem); 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); AddTail((struct List*)&pb->pb_WriteList, (struct Node*)ios2);
ReleaseSemaphore(&pb->pb_WriteListSem); ReleaseSemaphore(&pb->pb_WriteListSem);
Signal((struct Task*)pb->pb_Server, SIGBREAKF_CTRL_F); Signal((struct Task*)pb->pb_Server, SIGBREAKF_CTRL_F);
#endif
ios2 = NULL; ios2 = NULL;
} }
break; break;
+43 -10
View File
@@ -30,10 +30,10 @@ DEBUG EQU 1
; ;
;------------------ options, some depend on hardware (CPLD) configuration ------------------------- ;------------------ 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_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_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) _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 ifne DEBUG
; ;
@@ -1179,6 +1188,7 @@ _enc624j6l_SetMAC: ;set user defined MAC address
; testing with low turnaround time. ; testing with low turnaround time.
; ;
; In: A0 - Board base address ; In: A0 - Board base address
; D1 - flags
; ;
; Out: ; Out:
; D0 <= 0 - failure ; D0 <= 0 - failure
@@ -1205,9 +1215,9 @@ _enc624j6l_Init:
;33.333Mhz clock out frequency (see defines above) ;33.333Mhz clock out frequency (see defines above)
move.w #CLOCK_DEF_CLR,d0 ;clr mask move.w #CLOCK_DEF_CLR,d0 ;clr mask
move.w #CLOCK_DEF_SET,d1 ;set mask
CLRREG ECON2,a0,d0 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 ; 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 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 move #RXSTOP_INIT&$fffe,d0
WRITEREG ERXTAIL,a0,d0 ;tail pointer in buffer = rx-2, wraparound 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 move #(128<<8)|(32),d0 ;128*96=12288 high water mark, 32*96=3072 low water mark
WRITEREG ERXWM,a0,d0 WRITEREG ERXWM,a0,d0
moveq #MACON1_RXPAUS,d0 moveq #MACON1_RXPAUS,d0
SETREG MACON1,a0,d0 SETREG MACON1,a0,d0
move #ECON2_AUTOFC,d0 move #ECON2_AUTOFC,d0
SETREG ECON2,a0,d0 SETREG ECON2,a0,d0
else bra.s .init_flowdone
; else
.init_noflow:
move #ECON2_AUTOFC,d0 move #ECON2_AUTOFC,d0
CLRREG ECON2,a0,d0 ;disable automatic flow control CLRREG ECON2,a0,d0 ;disable automatic flow control
endc .init_flowdone:
; endc
;--------------- TX configuration ----------------------- ;--------------- TX configuration -----------------------
@@ -1595,7 +1612,12 @@ _enc624j6l_RecvFrame: ;
READREG PNextPacket,a0,d7 ;get user read pointer from private space READREG PNextPacket,a0,d7 ;get user read pointer from private space
;lea (a0,d7.w),a2 ;read ptr for next packet address ;lea (a0,d7.w),a2 ;read ptr for next packet address
;READREG 0,a2,d0 ;next packet pointer ;READREG 0,a2,d0 ;next packet pointer
READSRAM a0,d7,d0 ;move (a0,d7.w),d0 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 ;verify next packet pointer, re-initialize recv if this is invalid
cmp #RXSTOP_INIT,d0 ;bad pointer (<0 or >end of memory) cmp #RXSTOP_INIT,d0 ;bad pointer (<0 or >end of memory)
bhi.w .recv_err bhi.w .recv_err
@@ -1629,6 +1651,9 @@ _enc624j6l_RecvFrame: ;
;lea (a0,d7.w),a2 ;read ptr for first control word ;lea (a0,d7.w),a2 ;read ptr for first control word
;READREG 0,a2,d0 ;last control word = length (byte count) ;READREG 0,a2,d0 ;last control word = length (byte count)
READSRAM a0,d7,d0 ;move (a0,d7.w),d0 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) and.w #$f800,d0 ;verify (should be all zeros in upper 9 bits)
bne .recv_err ;receive buffer is wrong -> re-initialize 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 ;lea (a0,d7.w),a2 ;new read pointer for length
;READREG 0,a2,d0 ;last control word = length (byte count) ;READREG 0,a2,d0 ;last control word = length (byte count)
READSRAM a0,d7,d0 ;move (a0,d7.w),d0 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 ifne 1
;D1 is the distance to the next frame = stored length + recv vevtor ;D1 is the distance to the next frame = stored length + recv vevtor
@@ -1676,15 +1704,20 @@ _enc624j6l_RecvFrame: ;
endc endc
lea (a0,d7.w),a2 ;read pointer lea (a0,d7.w),a2 ;read pointer
move d0,d1 ;byte count 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 bcs.s .opt_read ;read 1 byte more if impair byte count
subq #1,d1 ;words - 1 subq #1,d1 ;words - 1
.opt_read: .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 rol.w #8,d2 ;swap buffer to Big Endian
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 endc
move d2,(a1)+
dbf d1,.opt_read dbf d1,.opt_read
bra.s .end_read bra.s .end_read
.nooptrecv: .nooptrecv:
+9 -3
View File
@@ -90,8 +90,8 @@
#define BOARD hwb->hwb_boards[0] #define BOARD hwb->hwb_boards[0]
/* interrupt (choice here is INTB_EXTER or INTB_PORTS, depending on solder blob */ /* interrupt (choice here is INTB_EXTER or INTB_PORTS, depending on solder blob */
#define HW_INTSOURCE INTB_EXTER /*#define HW_INTSOURCE INTB_EXTER */ /* Int 6 */
/*#define HW_INTSOURCE INTB_PORTS*/ #define HW_INTSOURCE INTB_PORTS /* Int 2 */
#endif #endif
@@ -193,6 +193,7 @@ GLOBAL REGARGS void hw_config_init(struct PLIPBase *pb)
hwb->hwb_fullduplex = 0; hwb->hwb_fullduplex = 0;
hwb->hwb_spispeed = 1; /* optimistic default */ hwb->hwb_spispeed = 1; /* optimistic default */
hwb->hwb_multicast = 0; 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; hwb->hwb_multicast = 1;
} }
if( args->flowcontrol )
{
hwb->hwb_flowcontrol = 1;
}
} }
@@ -355,9 +360,10 @@ GLOBAL REGARGS BOOL hw_attach(struct PLIPBase *pb)
flags = PIO_INIT_BROAD_CAST; flags = PIO_INIT_BROAD_CAST;
if( hwb->hwb_multicast ) if( hwb->hwb_multicast )
flags |= PIO_INIT_MULTI_CAST; flags |= PIO_INIT_MULTI_CAST;
if( hwb->hwb_fullduplex ) 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 #ifdef PROTO_ENC624NET
if( enc624j6l_Init( BOARD, (unsigned long)flags ) <= 0 ) 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 */
+7 -4
View File
@@ -39,9 +39,11 @@ struct HWBase
/* config options */ /* config options */
ULONG hwb_timervalue; /* timer speed */ 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_spispeed; /* SPI speed */
ULONG hwb_multicast; /* multicast enable */
}; };
#define HWB_RECV_PENDING 0 #define HWB_RECV_PENDING 0
@@ -57,8 +59,8 @@ struct HWBase
/* ----- config ----- */ /* ----- config ----- */
#define CONFIGFILE "ENV:SANA2/sdnet.config" #define CONFIGFILE "ENV:SANA2/enc624j6net.config"
#define TEMPLATE "TIMER/K/N,FULLDUPLEX/S,SPISPEED/K/N,MULTICAST/S" #define TEMPLATE "TIMER/K/N,FULLDUPLEX/S,SPISPEED/K/N,MULTICAST/S,FLOWCONTROL/S"
/* structure to be filled by ReadArgs template */ /* structure to be filled by ReadArgs template */
struct TemplateConfig struct TemplateConfig
@@ -68,6 +70,7 @@ struct TemplateConfig
ULONG fullduplex; ULONG fullduplex;
ULONG *spispeed; ULONG *spispeed;
ULONG multicast; ULONG multicast;
ULONG flowcontrol;
}; };
#endif #endif
+4 -4
View File
@@ -65,12 +65,12 @@ PUBLIC VOID SAVEDS ServerTask(void);
/*E*/ /*E*/
/*F*/ /* private */ /*F*/ /* private */
PRIVATE struct PLIPBase *startup(void); PRIVATE struct PLIPBase *startup(void);
PRIVATE REGARGS VOID DoEvent(BASEPTR, long event); PUBLIC REGARGS VOID DoEvent(BASEPTR, long event);
PRIVATE VOID readargs(BASEPTR); PRIVATE VOID readargs(BASEPTR);
PRIVATE BOOL init(BASEPTR); PRIVATE BOOL init(BASEPTR);
PRIVATE REGARGS BOOL goonline(BASEPTR); PRIVATE REGARGS BOOL goonline(BASEPTR);
PRIVATE REGARGS VOID gooffline(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 dowritereqs(BASEPTR);
PRIVATE REGARGS VOID doreadreqs(BASEPTR); PRIVATE REGARGS VOID doreadreqs(BASEPTR);
PRIVATE REGARGS VOID dos2reqs(BASEPTR); PRIVATE REGARGS VOID dos2reqs(BASEPTR);
@@ -161,7 +161,7 @@ PRIVATE REGARGS VOID dos2reqs(BASEPTR);
/* /*
** SANA-2 Event management ** SANA-2 Event management
*/ */
/*F*/ PRIVATE REGARGS VOID DoEvent(BASEPTR, long event) /*F*/ PUBLIC REGARGS VOID DoEvent(BASEPTR, long event)
{ {
struct IOSana2Req *ior, *ior2; struct IOSana2Req *ior, *ior2;
@@ -187,7 +187,7 @@ PRIVATE REGARGS VOID dos2reqs(BASEPTR);
/* /*
** writing packets ** 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; AW_RESULT rc;
struct HWFrame *frame = pb->pb_Frame; struct HWFrame *frame = pb->pb_Frame;
+3
View File
@@ -17,6 +17,9 @@ HWSRCDIR = enc624j6net
DEVICE_NAME = 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
##################################################################### #####################################################################
# #
# I keep various include trees, so for this project I directly reference # I keep various include trees, so for this project I directly reference