.TITLE GATILN Network Interlan Ethernet driver .NLIST BEX .ENABL LC ; ; Pdp11/dcn network Interlan Ethernet driver ; ; This module is an extension of the network processes. it transmits and ; receives packets using the Interlan NI2010A Ethernet DMA interface. ; ; Note: Board should be strapped for 18-bit operation (factory default). ; ; Conditional assembly switches ; .IIF NDF,CS.ILU CS.ILU == 0 ;0: q-bus version, 1: u-bus version ; ; External symbols ; .GLOBL .WAIT,.SKED ;supervisor services .GLOBL NETINP,NETOUT ;process initialization ; ; Entry symbols ; .GLOBL ILIPAT ;input process control vector .GLOBL ILOPAT ;output process control vector ; ; System definitions ; .ASECT .MCALL .COM,.PSA,.GAT,.PAT ;dcnlib definitions .MCALL .SETV ;dcnlib macros .MCALL $DFEH,.ETH ;moslib definitions .COM ;define common data .PSA ;define process stoage areas .GAT ;define gateway/bridge storage areas .ETH ;define ethernet storage areas $DFEH ;define header for farbling ; ; Module definitions ; QUESIZ = 10. ;max entries on queue QENSIZ = 3. ;size of a queue entry ; ; Command codes ; SILCMD = 002 ;set internal loopback CLMCMD = 003 ;clear loopback mode OFFCMD = 010 ;go offline ONLCMD = 011 ;go online SIACMD = 015 ;set insert-address mode CIACMD = 016 ;clear insert-address mode STACMD = 030 ;report statistics RCDCMD = 031 ;report collision delays LRCCMD = 040 ;load receive LTSCMD = 051 ;load transmit LGACMD = 052 ;load group address DGACMD = 053 ;delete group address RSTCMD = 077 ;reset controller ; ; Status codes ; OKSTA = 00 ;status ok RTYSTA = 01 ;success with retries ILLSTA = 02 ;illegal status INOSTA = 03 ;inapropriate status FAISTA = 04 ;failure BSESTA = 05 ;buffer size exceeded FTSSTA = 06 ;frame too small ECSTA = 10 ;excessive collisions BAESTA = 12 ;buffer alignmanet errors CRPSTA = 13 ;no heart beat NCESTA = 14 ;no error occurred ICESTA = 15 ;innapropriate crc error LDBSTA = 16 ;last data byte received incorrectly NEMSTA = 17 ;non-existant memory ; ; Status bits (csr) ; CMDDON = 000200 ;command done CMDIEN = 000100 ;command interrupt enable RCVDON = 000040 ;receive done RCVIEN = 000020 ;receive interrupt enable ; ; Parameter area extension (par) ; . = ETHLEN ETHDR: .BLKW 2 ;beginning of DMA'd statistics ETPA: .BLKW 3 ;physical address ETFR: .BLKW 1 ;# of frames received ETFRF: .BLKW 1 ;# of frames in RCV FIFO ETFT: .BLKW 1 ;# of frames transmitted ETXCOL: .BLKW 1 ;# of excess collisions ETCFRG: .BLKW 1 ;# of collisions fragments recv'd ETOVR: .BLKW 1 ;# times 1 or more frames lost ETMFA: .BLKW 1 ;# multicast frames accepted ETMFR: .BLKW 1 ;# multicast frames rejected ETCRCE: .BLKW 1 ;# recv'd with CRC errors ETALG: .BLKW 1 ;# recv'd with alignment errors ETCOL: .BLKW 1 ;# of collisions ETOWC: .BLKW 1 ;# of out-of-window collisions .BLKW 10 ;reserved (8) decimal ETMODID:.BLKW 4 ;module ID ETFRMID:.BLKW 4 ;firmware ID STATUS: .BLKW 1 ;active command ILRBLK: .BLKW 3 ;receive request block ILXBLK: .BLKW 3 ;transmit request block QUEPUT: .BLKW 1 ;put pointer QUEGET: .BLKW 1 ;get pointer QUEBGN: .BLKW 1 ;beginning of queue QUEEND: .BLKW 1 ;end of queue QUEUE: .BLKW QENSIZ*QUESIZ ;request queue ; ; Process save area extension (ilr) ; . = GATENR .BLKW REGEND/2+NTISTK ;process stack ILREND = . ;end of ilr extension ; ; Process save area extension (ilx) ; . = GATENX .BLKW REGEND/2+NTOSTK ;process stack ILXEND = . ;end of ilx extension ; ; Interlan device register block (dev) ; . = 0 ILNCSR: .BLKW 1 ;command and status register ILNBAR: .BLKW 1 ;buffer address register ILNBCR: .BLKW 1 ;byte count register ILNBER: .BLKW 1 ;buffer address extension register (not used) .PAGE ; ; Procedure segment ; ; Supervisor-state procedure ; Dsects: r2 = dev, r3 = par, r4 = reg, r5 = psa ; ; Note: calling process sets r0 = byte count, r1 = starting address. ; At completion of transfer r0 = byte count ; .PSECT $KERI,RO,I ; ; Initialize ; ILIINI: CLR STATUS(R3) ;clear active command MOV R3,R1 ;initialize command queue ADD #QUEUE,R1 MOV R1,QUEPUT(R3) MOV R1,QUEGET(R3) MOV R1,QUEBGN(R3) ADD #2*QENSIZ*QUESIZ,R1 MOV R1,QUEEND(R3) MOV R0,-(SP) ;initialize interface MOV R3,R0 ADD #ILRBLK+4,R0 MOV #66.,-(R0) ;(bcr) for dma commands MOV R3,-(R0) ;(bar) ADD #ETHLEN,@R0 MOV #INICMD,R1 ;execute initialization commands 1$: MOV (R1)+,4(R0) BEQ 2$ ;branch if done JSR PC,ENQUE BR 1$ ; 2$: MOV (SP)+,R0 BR ILINT ; ILOINI: ADD #4,R0 ;allocate output vector ILINT: MOV #INT+EXTBAS,R1 ;allocate input vector .SETV 1$: JSR PC,CMDSRV ;execute command TST ETPA(R3) ;wait for statistics to arrive BEQ 1$ MOV ETPA(R3),ETHADR(R3) ;etch ether address MOV ETPA+2(R3),ETHADR+2(R3) MOV ETPA+4(R3),ETHADR+4(R3) RTS PC ; ; Start block transfer input ; ILISIO: MOV R1,ILRBLK(R3) ;save transfer parameters MOV R0,ILRBLK+2(R3) MOV #LRCCMD*400+RCVIEN,ILRBLK+4(R3) MOV R3,R0 ;queue command ADD #ILRBLK,R0 JSR PC,ENQUE JSR PC,CMDSRV ;execute command JMP .WAIT ; ; Device interrupt input ; ILIINT: MOV ILRBLK(R3),R1 ;retrieve buffer address MOV EH.FL(R1),REGR0(R4) ;stash byte count ADD #4.,REGR0(R4) ;adjust for header JMP .SKED ; ; Reset link ; ILORST: RTS PC ;not used ; ; Start block transfer output ; ILOSIO: SUB #4,R0 ;adjust for header ADD #4,R1 MOV R1,ILXBLK(R3) ;save transfer parameters MOV R0,ILXBLK+2(R3) MOV #LTSCMD*400+CMDIEN+RCVIEN,ILXBLK+4(R3) MOV R3,R0 ;queue command ADD #ILXBLK,R0 JSR PC,ENQUE JSR PC,CMDSRV ;execute command JMP .WAIT ; ; Device interrupt output ; ILOINT: CLR STATUS(R3) ;declare completion MOV ILNCSR(R2),R0 ;is status ok BIC #^C17,R0 CMP R0,#1 BLOS 1$ ;branch if yes BIS #1,REGPS(R4) ;no. declare error 1$: JSR PC,CMDSRV ;execute next command JMP .SKED ; ; Subroutine to execute command ; CMDSRV: TST STATUS(R3) ;is command active BNE 3$ ;branch if yes MOV QUEGET(R3),R1 ;no. is queue empty CMP R1,QUEPUT(R3) BEQ 3$ ;branch if yes .IF EQ,CS.ILU ;conditional assembly for bus type CLR ILNBER(R2) ;no. start transfer .ENDC MOV (R1)+,ILNBAR(R2) MOV (R1)+,ILNBCR(R2) MOV @R1,ILNCSR(R2) MOV (R1)+,STATUS(R3) ;save csr CMP R1,QUEEND(R3) ;update queue pointer BLO 1$ MOV QUEBGN(R3),R1 1$: MOV R1,QUEGET(R3) BIT #CMDIEN,STATUS(R3) ;is interrupt armed BNE 3$ ;branch if yes 2$: BIT #CMDDON,ILNCSR(R2) ;no. is transfer complete BEQ 2$ ;branch if no CLR STATUS(R3) ;yes. try next command BR CMDSRV ; 3$: RTS PC ; ; Routine to queue command ; R0 = service block pointer ; ENQUE: MOV R0,-(SP) ;save for later MOV R1,-(SP) MOV QUEPUT(R3),R1 MOV (R0)+,(R1)+ ;(bar) MOV (R0)+,(R1)+ ;(bcr) MOV (R0)+,(R1)+ ;(csr) CMP R1,QUEEND(R3) ;update queue pointer BLO 1$ MOV QUEBGN(R3),R1 1$: MOV R1,QUEPUT(R3) MOV (SP)+,R1 MOV (SP)+,R0 RTS PC ; ; Data segment ; .PSECT $KERD,RO,D ; ; Process headers ; ILIPAT: .PAT ILREND,NETINP,PRI3,<0,0,ILIINI,ILISIO,ILIINT> ILOPAT: .PAT ILXEND,NETOUT,PRI3,<0,0,ILOINI,ILOSIO,ILOINT,ILORST> ; ; Initialization command list ; INICMD: .WORD CLMCMD*400 ;clear loopback mode .WORD ONLCMD*400 ;go online .WORD CIACMD*400 ;clear insert-address mode .WORD STACMD*400 ;get stats and physical address .WORD 0 ;end of list ; .END