New driver

This commit is contained in:
MHeinrichs
2019-01-03 00:43:32 +01:00
parent eecd6c8918
commit e42f097a6c
44 changed files with 1639 additions and 110 deletions
+127 -36
View File
@@ -18,10 +18,11 @@
; - RXSTART_INIT = $0c00 -> currently $2000 due to previous location bug
;
; incdir Temp:Amiga/src/Zorro-LAN-IDE.git/Driver/enc624j6net/
incdir src:baxnet/trunk/source/
;Temp:Amiga/src/Zorro-LAN-IDE.git/Driver/enc624j6net/
include "enc624j6net/registers.i"
include "enc624j6net/macros.i"
include lvo/exec_lib.i
; enable debugging code block
DEBUG EQU 1
;
@@ -34,7 +35,7 @@ ADD_4RX EQU 1 ;add 4 to valid RX size (fake CRC), fixes shapeshifter RAW treatme
PSTART_INIT EQU $0BF0 ; 16 Bytes private storage for driver
PSTOP_INIT EQU $0BFF ; (see below for definitions)
RXSTART_INIT EQU $2000 ; start of RX buffer, room for 14 packets
RXSTART_INIT EQU $0C00 ; start of RX buffer, room for 14 packets
RXSTOP_INIT EQU $5fff ; end of RX buffer
TXSTART_INIT EQU $0000 ; start of TX buffer, room for 2 packets
@@ -109,8 +110,9 @@ ENC_BOARDID EQU 123 ;ZII-IDE-LAN-CP
XDEF _enc624j6l_DisableInterrupt
XDEF _enc624j6l_EnableGlobalInterrupt
XDEF _enc624j6l_DisableGlobalInterrupt
XDEF _enc624j6l_broadcast_multicast_filter
XDEF _enc624j6l_bc_mc_filter
XDEF _enc624j6l_ReadPHY
;
; System includes
;
@@ -220,6 +222,11 @@ opendos:
tst.l d0
ble error
move.l _boardbase(pc),a0
; moveq #PHSTAT1,d0 ;AUTONEG DONE, forced speeds/duplex
moveq #PHSTAT3,d0 ;AUTONEG DONE, forced speeds/duplex
bsr _enc624j6l_ReadPHY
;---------- transmit test stuff ---------------
moveq #100,d2
.txtest:
@@ -530,7 +537,7 @@ _enc624j6l_Init:
moveq #ECON1_RXEN,d0 ;no RX, my dear (yet)
CLRREG ECON1,a0,d0 ;
;set clock out frequency (see defines above)
;33.333Mhz clock out frequency (see defines above)
move.w #CLOCK_DEF_CLR,d0 ;clr mask
CLRREG ECON2,a0,d0
move.w #CLOCK_DEF_SET,d0 ;set mask
@@ -545,7 +552,7 @@ _enc624j6l_Init:
WRITEREG ERXST,a0,d0 ;set RX start pointer (end will be $5fff)
WRITEREG PNextPacket,a0,d0 ;set user read pointer
bsr _enc624j6l_broadcast_multicast_filter ;in: A0/D1, out: D0
bsr _enc624j6l_bc_mc_filter ;in: A0/D1, out: D0
move #RXSTOP_INIT&$fffe,d0
WRITEREG ERXTAIL,a0,d0 ;tail pointer in buffer = rx-2, wraparound
@@ -604,7 +611,7 @@ _enc624j6l_Init:
; D1 - init flags
;out: D0 >0 = OK
; <=0 = FAIL
_enc624j6l_broadcast_multicast_filter:
_enc624j6l_bc_mc_filter:
move.l a0,d0
beq.s .rts
@@ -826,7 +833,7 @@ _enc624j6l_DisableInterrupt:
moveq #0,d0 ;magic trick: the board enables Interrupts
lea $4000(a0),a0
move.w d0,($4000,a0)
move.w d0,$4000(a0) ;was $4002
lea -$4000(a0),a0
;WRITEREG $8000,a0,d0 ;only with this "sesame"
@@ -892,14 +899,18 @@ _enc624j6l_IntServer_List:
bra.s .intdis_loop
.boardsdone:
ifne 1
;faster: get from extended Driver board list instead from ZII/ZIII card
ifne 1
move.l (a6)+,d0 ;Sigtask
move.l (a6)+,d0 ;SigTask
beq.s .rts
move.l d0,a1
move.l (a6)+,d1 ;SigBit
move.l d0,a1 ;SigTask
move.l (a6)+,a6 ;ExecBase
moveq #0,d0
move.l (a6)+,d1 ;Sigbit
bset d1,d0
else
@@ -915,10 +926,11 @@ _enc624j6l_IntServer_List:
READREG PSigBit,a0,d1 ;get signal bit
bset d1,d0 ;signal mask
move.l 4.w,a6
endc
move.l 4.w,a6
jsr _LVOSignal(a6)
jsr _LVOSignal(a6)
.rts
move.l (sp)+,a6
@@ -1083,8 +1095,9 @@ _enc624j6l_HaveRecv:
move.l a0,d0
beq.s .err
READREG ESTAT,a0,d0
and.l #$ff,d0 ;ESTAT_PKTCNT7...ESTAT_PKTCNT0
moveq #0,d0
READREG ESTAT,a0,d1
move.b d1,d0 ;ESTAT_PKTCNT7...ESTAT_PKTCNT0
.rts:
rts
.err: moveq #-1,d0
@@ -1112,8 +1125,9 @@ _enc624j6l_RecvFrame: ;
move.l a0,d1
beq .err
READREG ESTAT,a0,d0 ;number of pending frames
and.l #$ff,d0 ;clear out count (ESTAT_PKTCNT7...ESTAT_PKTCNT0)
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
@@ -1280,12 +1294,6 @@ _enc624j6l_RecvFrame: ;
bge.s .rts
moveq #0,d0
; cmp.l #$d8803977,6(a3)
; beq .rts
; moveq #0,d0
; clr.l 6(a3)
.rts:
movem.l (sp)+,d2-d7/a1-a3
rts
@@ -1319,7 +1327,7 @@ _enc624j6l_RecvFrame: ;
; notes:
;
_enc624j6l_TransmitFrame:
movem.l d2-d4/a2,-(sp)
movem.l d2-d5/a2,-(sp)
;---------------- parameter check -------------------------------------
@@ -1344,13 +1352,6 @@ _enc624j6l_TransmitFrame:
move.l a1,d1 ;no send frame ?
beq.w .err ;exit
move.w d0,d4 ;still need length later
addq #7,d0 ;round up
asr.w #3,d0 ;size/8 = words
subq.w #1,d0 ;dbf...
blt.w .err ;size<2 ? bail out
;------ double-buffered frame copy to send buffer ---------------------
READREG PNextTX,a0,d2 ;"last written, maybe still pending frame"
and.w #PSwapTX,d2 ;sanity, leave only desired bits
@@ -1358,6 +1359,40 @@ _enc624j6l_TransmitFrame:
WRITEREG PNextTX,a0,d2 ;remember pointer (d2 also for ETXST later)
lea (a0,d2.w),a2 ;write pointer for frame
ifeq _OPT_BUFFER_SWAP
;faster TX when buffer swapping is not necessary
move.l d0,d4 ;remember length
moveq #63,d5 ;
and.l d5,d0 ;remainder of 64 byte copy loop
move.l d4,d5 ;length in bytes
asr.w #6,d5 ;64 byte blocks
subq.w #1,d5 ;dbf
blt.s .smallcopy
bra.s .largecopy_start
.largecopy:
move.l d1,(a2)+
.largecopy_start:
rept 15
move.l (a1)+,(a2)+ ;save to SRAM
endr
move.l (a1)+,d1
dbf d5,.largecopy
move.l d1,(a2)+
bra.s .smallcopy
endc ;_OPT_BUFFER_SWAP
move.w d0,d4 ;still need length later
.smallcopy:
addq #7,d0 ;round up
asr.w #3,d0 ;size/8 = words
subq.w #1,d0 ;dbf...
blt.w .err ;size<2 ? bail out
swap d4
move.w #8,d4
.txcopy:
@@ -1375,14 +1410,16 @@ _enc624j6l_TransmitFrame:
swap d3
move.l d1,(a2)+ ;save to SRAM
move.l d3,(a2)+ ;save to SRAM
else
else ;_OPT_BUFFER_SWAP
move.l (a1)+,(a2)+ ;save to SRAM
move.l (a1)+,(a2)+ ;save to SRAM
endc
endc ;_OPT_BUFFER_SWAP
dbf d0,.txcopy
swap d4
;---------------- wait on last frame ----------------------------------
move #200,d3
.txwait:
@@ -1410,7 +1447,7 @@ _enc624j6l_TransmitFrame:
SETREG ECON1,a0,d1 ;
.err:
movem.l (sp)+,d2-d4/a2
movem.l (sp)+,d2-d5/a2
rts
ifne _OPT_CHECKLINK_TX
@@ -1422,7 +1459,61 @@ _enc624j6l_TransmitFrame:
bra.s .linkchgdone
endc
;---------------------------------------------------------------------------------------
;
; read PHY register (16 Bit)
;
; input: A0 - APTR mmapped board base address
; D0 - LONG Phy register (5 valid bits)
;
; output: LONG D0 <0 - error (bad register index)
; - 16 Bit PHY reg contents
;
; trash: -
;
; notes:
;;
;
;
_enc624j6l_ReadPHY:
moveq #31,d1
cmp.l d1,d0
bhi.w .err
bset #8,d0 ;$100 + PHY_REG
WRITEREG MIREGADR,a0,d0 ;set PHY register address
moveq #1,d0
WRITEREG MICMD,a0,d0 ;read command
moveq #25,d0 ;25 us delay (at least)
bsr _enc624j6l_UMinDelay ;
moveq #100,d1
.waitloop:
READREG MISTAT,a0,d0
btst #0,d0
beq.s .notbusy
tst.b $BFE301 ;1 CIA access = 1.4 us
subq.w #1,d1 ;>165 us exceeded ? -> something is wrong, SPEC says 25.6 us
blt.s .notbusy ;error
bra.s .waitloop
.notbusy
moveq #0,d0
WRITEREG MICMD,a0,d0 ;cancel read command
tst.w d1 ;did we run into timeout ?
blt.s .err ;yes, we don't have anything worthwhile
READREG MIRD,a0,d1
moveq #0,d0
move.w d1,d0
rts
.err:
moveq #-1,d0
rts
;------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------
;
+14 -1
View File
@@ -232,7 +232,7 @@ ASM SAVEDS int enc624j6l_SetOnline( ASMR(a0) void *board ASMREG(a0) );
output: <0 - error
>=0 - OK
*/
ASM SAVEDS int enc624j6l_broadcast_multicast_filter(
ASM SAVEDS int enc624j6l_bc_mc_filter(
ASMR(a0) void *board ASMREG(a0),
ASMR(d1) unsigned long flags ASMREG(d1) );
@@ -326,6 +326,19 @@ ASM SAVEDS void enc624j6l_IntServer_List( void );
*/
ASM SAVEDS int enc624j6l_CheckLinkChange( ASMR(a0) void *board ASMREG(a0) );
/*
Purpose: read PHY register
input: board - mmapped board base address
flags - broadcast,promiscous, multicast
output: <0 - error
>=0 - OK
*/
ASM SAVEDS int enc624j6l_ReadPHY(
ASMR(a0) void *board ASMREG(a0),
ASMR(d0) unsigned long phyreg ASMREG(d0) );
#endif /* _INC_ENC624J6L_H */
@@ -0,0 +1,110 @@
/*
enc624test.c
(C) 2018 Henryk Richter <henryk.richter@gmx.net>
Matze-Scrat-Buggs ZII card hardware test
*/
#include <exec/libraries.h>
#include <proto/exec.h>
#define ENC_MANUFACTURER 2588
#define ENC_BOARD 123
#include <proto/expansion.h>
#include <proto/dos.h>
#include <libraries/configvars.h>
#include <hardware/intbits.h>
#if 0
#include "device.h"
#include "hw.h"
#include "enc624j6l.h"
#endif
#include "registers.h"
#define READREG(_x_,_off_) *( (volatile USHORT*)( (volatile UBYTE*)(_x_) + (_off_)) )
#define WRITEREG(_x_,_off_,_y_) *( (volatile USHORT*)( (volatile UBYTE*)(_x_) + (_off_)) ) = (_y_);
#define SETREG(_x_,_off_,_y_) *( (volatile USHORT*)( (volatile UBYTE*)(_x_) + (_off_) + SET_OFFSET )) = (_y_);
#define CLRREG(_x_,_off_,_y_) *( (volatile USHORT*)( (volatile UBYTE*)(_x_) + (_off_) + CLR_OFFSET )) = (_y_);
const BYTE exp_name[] = "expansion.library";
int main( int argc, char **argv )
{
LONG ret = 0;
ULONG ul;
volatile APTR board = (0);
volatile UBYTE *uboard;
struct Library *ExpansionBase;
struct ConfigDev *cfg = (0);
ExpansionBase = OpenLibrary( (BYTE*)exp_name, 37 );
if( !ExpansionBase )
{
Printf("Cannot open Expansion. quitting\n");
goto quit;
}
cfg = FindConfigDev( cfg, ENC_MANUFACTURER, ENC_BOARD );
if( cfg )
{
board = (volatile APTR)cfg->cd_BoardAddr;
}
if( !board )
{
Printf("Board %ld / %ld not found in expansions\n",(ULONG)ENC_MANUFACTURER,(ULONG)ENC_BOARD);
goto quit;
}
Printf("Board found at 0x%lx\n",(ULONG)board);
/* 16 Bit R/W Test */
Printf("16 Bit reg test\n",(ULONG)board);
WRITEREG( board, EUDAST, 0x1234 );
ul = READREG( board, EUDAST );
if( ul != 0x1234 )
{
Printf("Board error: wrote 0x1234, got 0x%lx\n",ul);
ret = 1;
}
WRITEREG( board, EUDAST, 0x0000 );
/* Byte R/W tests */
Printf("8 Bit buffer tests\n",(ULONG)board);
WRITEREG( board, 0xBFE, 0x0000 );
uboard = (volatile UBYTE*)board;
*(uboard+0xBFE) = 0xda;
ul = READREG( board, 0xBFE );
if( ul != 0xda00 )
{
Printf("Board error: expected 0xDA00, got 0x%lx on upper byte test\n",ul);
ret = 1;
}
WRITEREG( board, 0xBFE, 0x0000 );
*(uboard+0xBFF) = 0xbf;
ul = READREG( board, 0xBFE );
if( ul != 0x00bf )
{
Printf("Board error: expected 0x00BF, got 0x%lx on lower byte test\n",ul);
ret = 1;
}
if( ret )
Printf("Error(s) encountered\n");
else
Printf("Board looking good as far as tested\n");
quit:
if( ExpansionBase )
CloseLibrary(ExpansionBase);
return ret;
}
+64 -6
View File
@@ -3,7 +3,7 @@
(C) 2018 Henryk Richter <henryk.richter@gmx.net>
SDNet hardware interface to device
Matze-Scrat-Buggs ZII card hardware interface to device
*/
@@ -73,6 +73,8 @@ void myhw_ControlIntervalTimer( DEVBASEP );
hw_config_init() - set defaults for HW
hw_config_update() - update config of HW
hw_get_mac_status() - running parameters
*/
const BYTE exp_name[] = "expansion.library";
@@ -85,11 +87,10 @@ ASM SAVEDS LONG hw_Find_Boards( ASMR(a0) DEVBASEP ASMREG(a0) )
struct Library *ExpansionBase;
struct ConfigDev *cfg = (0);
if( (ExpansionBase = OpenLibrary( exp_name, 37 )) )
if( (ExpansionBase = OpenLibrary( (BYTE*)exp_name, 37 )) )
{
/* TODO: check for expansion port, i.e. distinguish V500/V600 */
/* TODO: actually verify that we have a module here */
ret = 1;
/* ret = 1; */
for( i=0 ; i < MAX_UNITS ; i++ )
{
@@ -322,8 +323,64 @@ ASM SAVEDS LONG hw_check_link_change( ASMR(a0) DEVBASEP ASMREG(
return 1; /* don't signal panic to the outside, everything is under control */
}
/* obtain running parameters of Ethernet MAC: link up/down, Speed, Duplex */
ASM SAVEDS LONG hw_get_mac_status( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0) )
{
struct HWData *hwd = &db->db_hwdat;
APTR boardbase = db->db_Units[unit].duh_BASE;
LONG ret;
LONG phstat3;
LONG phstat1;
LONG phcon1;
enc624j6l_ReadPHY( boardbase, PHSTAT1 );
phstat3 = enc624j6l_ReadPHY( boardbase, PHSTAT3 );
phcon1 = enc624j6l_ReadPHY( boardbase, PHCON1 );
phstat1 = enc624j6l_ReadPHY( boardbase, PHSTAT1 ); /* read again to see whether link is established */
if( ( phstat1 < 0 ) || ( phstat3 < 0 ) )
return HW_MAC_INVALID; /* no valid data found */
/* a) check Link */
ret = 0;
if( phstat1 & PHSTAT1_LLSTAT )
{
ret |= HW_MAC_LINK_UP;
/* if( phstat1 & PHSTAT1_ANDONE ) */ /* autonegotiation successful */
if( phcon1 & PHCON1_ANEN ) /* autonegotiation enabled */
ret |= HW_MAC_AUTONEGOTIATION;
phstat3 = (phstat3>>2)&7; /* get active Speed/Duplex */
switch( phstat3 )
{
case 6:
if( hwd->flowcontrol )
ret |= (HW_MAC_ON_FDX_FC<<HW_MACB_SPEED100);
else
ret |= (HW_MAC_ON_FDX<<HW_MACB_SPEED100);
break;
case 5:
if( hwd->flowcontrol )
ret |= (HW_MAC_ON_FDX_FC<<HW_MACB_SPEED10);
else
ret |= (HW_MAC_ON_FDX<<HW_MACB_SPEED10);
break;
case 2: ret |= (HW_MAC_ON<<HW_MACB_SPEED100);
break;
case 1: ret |= (HW_MAC_ON<<HW_MACB_SPEED10);
break;
default: break;
}
}
return ret;
}
ASM SAVEDS LONG hw_change_multicast( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(a0) ULONG unit ASMREG(d0),
ASMR(d0) ULONG unit ASMREG(d0),
ASMR(a1) struct List *mcastlist ASMREG(a1) )
{
/* TODO: implement Multicast hashing */
@@ -339,7 +396,7 @@ ASM SAVEDS LONG hw_change_multicast( ASMR(a0) DEVBASEP ASMREG(
if( mcastlist->lh_Head->ln_Succ )
flags |= PIO_INIT_MULTI_CAST;
enc624j6l_broadcast_multicast_filter(boardbase, flags );/* flags & (PIO_INIT_BROAD_CAST|PIO_INIT_MULTI_CAST) ); */
enc624j6l_bc_mc_filter(boardbase, flags );/* flags & (PIO_INIT_BROAD_CAST|PIO_INIT_MULTI_CAST) ); */
@@ -366,6 +423,7 @@ void myhw_ControlInterrupts( DEVBASEP )
hwd->hwd_act_boards[flag] = (0); /* NULL-terminate */
hwd->hwd_act_boards[flag+1] = (APTR)FindTask(0); /* append task */
hwd->hwd_act_boards[flag+2] = (APTR)hwd->hwd_IntSig; /* append sigbit */
hwd->hwd_act_boards[flag+3] = (APTR)db->db_SysBase; /* append ExecBase *((APTR*)0x4); */
if( flag ) /* determine on/off switch */
{
+4 -1
View File
@@ -15,11 +15,14 @@
/* sdnet/v2expnet specific: polling timer */
#include "intervaltimer.h"
#define HW_VENDOR "a1k.org Matze Buggs Scrat"
#define HW_PRODUCT "Zorro LAN IDE CP"
/* this struct is available in devicebase and should carry global information */
struct HWData {
struct Interrupt hwd_Interrupt; /* keep the interrupt at top of HWData !! */
struct SignalSemaphore hwd_Sem; /* list locking (global per unit) */
APTR hwd_act_boards[MAX_UNITS+1+2]; /* poll all active boards by ptr in interrupt, NULL terminated, followed by SigTask,Sigbit */
APTR hwd_act_boards[MAX_UNITS+1+3]; /* poll all active boards by ptr in interrupt, NULL terminated, followed by SigTask,Sigbit,ExecBase */
ULONG hwd_SigMask; /* signal mask to wait for in server main instance */
@@ -439,6 +439,17 @@
#define EIDLED_REVID1 (1<<1)
#define EIDLED_REVID0 (1)
/* ; PHY REGISTERS */
#define PHCON1 0
#define PHSTAT1 1
#define PHANA 4
#define PHANLPA 5
#define PHANE 6
#define PHCON2 0x11
#define PHSTAT2 0x1b
#define PHSTAT3 0x1f
/* PHCON1 bits --------- */
#define PHCON1_PRST (1<<15)
#define PHCON1_PLOOPBK (1<<14)
@@ -437,6 +437,16 @@ EIDLED_REVID2 EQU (1<<2)
EIDLED_REVID1 EQU (1<<1)
EIDLED_REVID0 EQU (1)
; PHY REGISTERS
PHCON1 EQU 0
PHSTAT1 EQU 1
PHANA EQU 4
PHANLPA EQU 5
PHANE EQU 6
PHCON2 EQU $11
PHSTAT2 EQU $1b
PHSTAT3 EQU $1f
; PHCON1 bits ---------
PHCON1_PRST EQU (1<<15)
PHCON1_PLOOPBK EQU (1<<14)
@@ -598,5 +608,6 @@ CLOCK_16_SET EQU (ECON2_COCON2) ;set mask
CLOCK_4_CLR EQU (ECON2_COCON2) ;clr mask
CLOCK_4_SET EQU (ECON2_COCON3|ECON2_COCON0|ECON2_COCON1) ;set mask
; changed to 25 MHz for ZIII firmware
CLOCK_DEF_CLR EQU CLOCK_25_CLR
CLOCK_DEF_SET EQU CLOCK_25_SET