home *** CD-ROM | disk | FTP | other *** search
- ;************************************************************************;
- ;* *;
- ;* *;
- ;* Interlan Ni5210/Ni9210 Ethernet Driver Software *;
- ;* *;
- ;* Rev Author Date Description *;
- ;* --- ------ ---- ----------- *;
- ;************************************************************************;
-
- ;==============( description )============================================
-
- ; NIDRLnn.M86 The "real" 82586 device driver logic whose
- ; workings are, for the most part, independent of
- ; which network interface products are supported.
- ; The last two digits are undefined and used during
- ; development as a file version number.
- ;
- ; NIDRLnn.M86 establishes data area definition by
- ; including NIDRD.M86 with NIDR_DATA_DECL = FALSE.
- ;
- name IPXDRIVERMODULE
-
- %set (NISH_DATA_DECL,0) ; only define data areas
-
- $include (..\h\nishd.inc) ; shared with product interfaces
- $include (..\h\assert.equ)
-
-
- $include (..\h\side.inc)
-
- ;==============( data definition )===================================
-
-
- %set (NIDR_DATA_DECL,0) ; only define data areas
-
- $include (..\h\nidrd.inc) ; data declare file
-
-
- ;==============( test whw )=========================================
-
-
-
- public ReStart586, RUStart, RUSuspend
-
- ;
- ; The following routines are declared public to aid in debugging:
- ;
-
- public Wait586, Command586, IssueCA
- public Configure586, ProcessFRInt, ReturnReceivedBuffer
- public ProcessCXInt, TransmitPacket
- public InputLoop, unmaskint, SetUpReads, InitTxBuffs
-
-
- %rcode_seg
-
- Even
-
- InitialSCP db 0 ; 16 bit bus
- db 5 dup (0)
- dw ISCP
- dw 0
-
- ; Initial ISCP
- dw 1
- dw SCB
- dw 0, 0
-
- ;
- ; Ethernet Configuration
- ;
- public ConfigNormal ; allow external reference
- Config_4_Normal dw 0,8002h,0,40Ch,2E00h,6000h,0F200h,0h,40h
-
- $Eject
-
- ;
- ; RUStart
- ;
- ; Checks the status of the Receiver and if there are enough
- ; resources, starts the receiver.
- ;
- ; This code is a critical section since in the 3COM port it can
- ; be called from both base and interrupt level.
- ;
- ; Called by :
- ; AT_Isr
- ; PC_Isr
- ; ReStart586
- ; SetUpReads
- ; WrRxFilter
- ;
- Assume cs: %CGroup, ds: NiMemSeg, es: NiMemSeg
-
- RUStart proc near
-
-
- mov al, byte ptr SCB.SCBStatus
- and al, 70h ; strip out RUS
- cmp al, 40h ; ready ?
- je NoStart
-
- mov bx, FDHead ; must have 2 fd's and RDB's to start
- cmp [bx].FDCommand, 8000h ; is this the last FD?
- je NoStart ; if e, yes - return
-
- mov si, RBDHead
- cmp si, EndOfQue ; check for 1st RBD
- je NoStart
-
- cmp [si].BDLink, EndOfQue ; check for 2nd RBD
- je NoStart
-
- push ds
- %get_dataseg
- mov ds, ax
-
- inc ds: RxStartCount ; update counter
-
- ; SCB errors counters are managed by the 586 chip, so we just need
- ; to copy them. We do so every time the receiver needs to be restarted
-
- mov ax, SCB.RUNTerror
- mov ds: PacketRxTooSmallCount, ax
- mov ax, es: SCB.CRCerror
- mov ds: ChecksumErrorCount, ax
- mov ax, es: SCB.NRerror
- mov ds: RxLostCount, ax
-
- pop ds
-
- mov DummyRBD.BufSize, 8000h ; 0 length RBD with EL at EOL
- mov DummyRBD.BDlink, EndOfQue ; dummy link
- mov [bx].RBDOffset, si
- call wait586
- jnz NoStart
-
- mov SCB.RFAOffset, bx
- mov SCB.SCBCommand, 10h ; ru start
- call IssueCA
- NoStart:
- ret
- RUStart endp
-
- $Eject
- ;
- ; Configure586 must run disabled!
- ; Called by :
- ; ReStart586
- ; DriverInitialize
-
- Assume cs: %CGroup, ds: NiMemSeg, es: NiMemSeg, ss: Nothing
-
- Configure586 proc near
-
- mov ax, cs
- mov ds, ax
-
- lea si, InitialScp ;Set up SCP and ISCP
- mov di, es: SCP
- mov cx, SCPLen/2
- rep movsw
- lea di, ISCP
- mov cx, ISCPLen/2
- rep movsw
-
- mov ax, es
- mov ds, ax
-
- xor ax, ax
- mov bx, ax
- call Command586
-
- call Wait586
- push ds
-
- mov ax, cs
- mov ds, ax
-
- mov si, ConfigPointer
- mov cx, size ConfigNormal / 2
- lea di, CommandBuff
- mov bx, di
- rep movsw
- pop ds
-
- mov ax, 100h ;do command
- call Command586
-
- WaitCC:
- mov ax, [bx]
- test ax, 8000h ;command complete?
- jz WaitCC
-
- xor ax, ax
- mov di, bx
- stosw ;set up ia command
- mov [di], 8001h
- inc di
- inc di
- stosw
-
- mov ax, cs ; DS -> code segment
- mov ds, ax
-
- lea si, DNodeAddress
- movsw
- movsw
- movsw
-
- mov ax, es
- mov ds, ax
-
- mov ax, 100h
- call Command586
- ret
-
- Configure586 endp
- $Eject
-
-
- ;
- ; Driver Initialization Code follows. In the Novell environment this
- ; segment is thrown away after shell installation is complete.
- ; When running in a 3COM environment, driver initialization code
- ; can not be thrown away since it is not executed until initialization
- ; is requested by 3Com programs (ie. initialization is not done at
- ; load time).
- ;
-
- %initnet_seg
-
- public %SideDriverInitialize
-
- ; Driver Initialize Segment Data area
-
- NodeIdAddress dw 0
-
- %if (%NI5210) then (
- OldInterrupt dd 0 ; 9210 contains old vector in ISR
- ) fi
-
- NiNotFoundMsg db 'Ni9210 not found at I/O address. - Check Jumpers.$'
- NiMemNotFoundMsg db 'Ni9210 memory not found - Check Jumpers.$'
-
-
- $Eject
- ;
- ; Driver Initialize
- ;
- ; assumes:
- ; DS, ES are set to CGroup (== CS)
- ; DI points to where to stuff my address (if NOT running as Novell srvr)
- ; Interrupts are ENABLED
- ; The Real Time Ticks variable is being set, and the
- ; entire AES system is initialized.
- ;
- ; returns:
- ; If initialization is done OK:
- ; AX has a 0
- ; If board malfunction:
- ; AX gets offset (in CGroup) of '$'-terminated error string
- ;
- Assume cs: %CGroup, ds: %DGroup, es: NiMemSeg
-
- %SideDriverInitialize
- & proc near
-
- cld
-
- mov NodeIdAddress, di ; Save address for ether node address
- mov MaxPhysPacketSize, 1024
- mov ReadWriteCycles, 100
- mov cs: DataGp, ds
-
- call GetMachType ; returns machine type in AL
- mov MachineType, al
-
- xor ah,ah
- %trace_x(IBM Machine ID: ,ax)
-
- Get_Configuration:
- call GetConfig ; initialize NI configuration params
- or ax, ax
- jz Display
- jmp DIExit
-
- Display:
-
- call WriteConfig ; display configuration params
-
- lea ax, Config_4_Normal
- mov ConfigPointer,ax
- ;
- ; verify that the NI card exists
- ;
- NiExists:
- %GetNiPort(6) ; Read ethernet rom check id (00, 55)
- in al, dx ; al should contain 00
- mov ah, al ; store in high byte
-
- %GetNiPort(7)
- in al, dx ; al should contain 55
- cmp ax, 0055h
- je ZeroCounters
-
- lea ax, NiNotFoundMsg
- jmp DIExit
-
- ZeroCounters:
- xor ax, ax ; zero counters
- mov TotalTxPacketCount, ax
- mov TotalTxPacketCount+2, ax
- mov TotalRxPacketCount, ax
- mov TotalRxPacketCount+2, ax
- mov NoECBAvailableCount, ax
- mov PacketTxTooSmallCount, ax
- mov PacketRxOverflowCount, ax
- mov PacketRxTooBigCount, ax
- mov PacketRxTooSmallCount, ax
- mov PacketTxMiscErrorCount, ax
- mov PacketRxMiscErrorCount, ax
- mov RetryTxCount, ax
- mov ChecksumErrorCount, ax
- mov HardwareRxMismatchCount, ax
- mov NotNetwarePacketCount, ax
- mov Restart586Count, ax
- mov RxStartCount, ax
- mov RxLostCount, ax
-
- ;
- ; Calculate the number of transmit buffers. Note that 3COM
- ; does not have as great a need for transmit buffers as does
- ; Novell.
- ;
- cmp NiMemSize, 8
- jne MemSize16
-
- mov Memend, 1fffh ; set values for 8k memory
- mov TmpSCP, 1FF6h
- mov NumTxBuffs,1
- jmp short MemSizeDone
-
- MemSize16:
- cmp NiMemSize,16
- jne MemSize64
-
- mov Memend, 3fffh ; set values for 16K memory
- mov TmpSCP, 3FF6h
- mov NumTxBuffs,2
- jmp short MemSizeDone
- ;
- MemSize64:
- mov Memend,0FFFFh
- mov TmpSCP, 0FFF6h
- mov NumTxBuffs,4
-
- MemSizeDone:
- mov ax, NumTxBuffs
- %trace_x(Transmit buffers:,NumTxBuffs)
-
- mov es, NiMemLoc ; ES -> NI buffer memory
-
- ClearMemory:
- xor ax, ax
- mov di, ax
- mov cx, Memend
- shr cx, 1
-
- rep stosw
-
- mov cx, TmpSCP
- mov SCP, cx
-
- ResetCard:
- %GetNiPort(0) ; Reset Ni5210 586
- out dx, al
-
- call SetNodeAddress ; set DNodeAddress
-
- Set_Vector:
- cli
- mov ax, NiIRQ ; interrupt line number
- mov bx, Offset %CGroup: AT_Isr ; handler address
- call SetInterruptVector
- mov SlavePICUsed, al
-
- xor ah,ah
- %trace_x(Slave PIC usage: ,ax)
-
- mov es, NiMemLoc ; ES -> NiMemSeg
- mov cx, es ; DS -> NiMemSeg
- mov ds, cx
-
- call Configure586
-
- call InitTxBuffs
-
- call SetUpReads
-
- mov DeadMan, DeadManTimeOut ;init Deadman Counter
- mov TransmitFlag, FALSE
-
- sti
-
- %get_dataseg
- mov ds, ax ; DS -> DGroup
- mov es, ax ; ES -> DGroup
-
- xor ax, ax ; enable network connection
- %GetNiPort(3)
- out dx, al
-
- lea si, DNodeAddress
- mov di, NodeIdAddress
-
- movsw
- movsw
- movsw
-
- mov es, NiMemLoc
- call unmaskint ; unmask device interrupts
-
- xor ax, ax
- mov cx, 1 ; transport time
-
- DIExit:
- ret
-
- %SideDriverInitialize endp
- ;
- ;
- ; Set Interrupt Vector
- ;
- ; Inputs:
- ; ax - Interrupt Request Number (1-11)
- ; bx - Interrupt Handler's Address
- ;
- ; Returns:
- ; al - non-zero if the driver needs to do an extra EOI
- ;
- ; Modified:
- ; NiVector - Interrupt vector address
- ; NiMask - PIC mask to disable interrupts
- ; NiUnmask - PIC mask to enable interrupts
- ; OldInterrupt - Address of former handler for this interrupt
- ;
- ; Called by:
- ; DriverInitialize
- ;
- ; Logic:
- ;
- ; if (SlavePICUsed) -- for int levels 2, 8-15
- ; if (irq == 2)
- ; NiVector = 71h;
- ; else NiVector = irq + 68h;
- ; else NiVector = irq + 8;
- ;
- ; if (SlavePICUsed)
- ; Level_7_Vector = 77h;
- ; else Level_7_Vector = 15;
- ;
- ; get and set level 7 isr, ni5210 isr, and timer isr;
- ;
- ; NiMask = 2 ^ NiIRQ;
- ; NiUnmask = NOT ( 2 ^ NiIRQ );
- ;
-
- SetInterruptVector proc near
-
- push bp
- mov bp, sp
- sub sp, local_siz
-
- mov ISRptr[bp], bx ; save ISR handler's address
-
- xor bx, bx
- mov bl, false ; determine if the 2nd PIC is being used
-
- cmp MachineType, MachID_AT ; if machine is an AT or PS/2
- jg SIV00
-
- cmp ax, 2 ; ... and if IRQ is 2 ...
- jne Slave_10
-
- mov bl, true
- jmp SIV00
-
- Slave_10:
- cmp ax, 8 ; ... or IRQ is 8 - 15
- jl SIV00
-
- mov bl, true ; the slave PIC is in use
-
- SIV00:
- mov word ptr PICboolean[bp], bx ; save slave PIC boolean
-
- cmp bl, true ; compute vector number
- jne SIV10
-
- cmp ax, 2
- jne SIV05
-
- mov NiVector, 71h ; AT's IRQ2 => IRQ9
- jmp get_7_vector
-
- SIV05:
- add ax, 68h ; 70h == 2nd PIC's interrupt base
- mov NiVector, ax
- jmp get_7_vector
-
- SIV10:
- add ax, 08h ; 8 is 1st PIC's interrupt base
- mov NiVector, ax
-
- get_7_vector:
-
- mov ax, NiVector ; get vector
- push es ; Save buffer segment
- mov ah, 35h ; Get old vector
- int 21h
-
- mov Word Ptr cs:Oldinterrupt, bx
- mov Word Ptr cs:OldInterrupt + 2, es
-
- pop es
- mov dx, ISRptr[bp] ; get ISR's address
- mov ah, 25h ; Set new vector
- int 21h
-
-
- ;
- ; need to compute mask, unmask values
- ;
- mov cl, byte ptr NiIRQ ; Interrupt number
- mov ah, 0FEH
- mov al, 01H
- rol ah, cl
- rol al, cl
- mov NiMask, al ; interrupt mask value
- mov NiUnmask, ah ; interrupt unmask value
-
- SIV40:
- mov ax, word ptr PICboolean[bp] ; fetch Slave PIC boolean
-
- mov sp, bp
- pop bp
- ret
-
- SetInterruptVector endp
-
- ;------------------------------------------------------------------- GetConfig
- ;
- ; Intialize configuration parameters (i/o base, interrupt level, etc)
- ; for the NI card. In case an error of some sort is encountered,
- ; the Novell version returns the address of an error string and the
- ; 3COM version returns an error number.
- ;
- ; This procedure will search thru the slots for Our Adapter. When
- ; found, we will read the information contained in the POS registers
- ; and enable the card.
- ;
- ; Called by:
- ; DriverInitialize
- ;
- ; Modifies:
- ; NiMemLoc, NiIRQ, NiPort, Ni9210IntPort,
- ; NiMemSize, Ni9210BusArb, Ni9210Master
- ;
- ; Returns:
- ; ax: 0 = all okay
- ; nonzero = error, references error descriptor
- ;
- ;-----------------------------------------------------------------------------
- IRQ_TABLE db 9 ; Interrupt Value 0
- db 10 ; Interrupt Value 1
- db 11 ; Interrupt Value 2
- db 3 ; Interrupt Value 3
-
- Assume cs: %CGroup, ds: %DGroup, es: NiMemSeg
-
- GetConfig proc near
-
- mov bx, %SideCard
- mov cx, 8
- Get_05:
- ; ; Select a Adapter
- ; ; 0,7,6,5,4,3,2,1
- mov ax, cx
- or ax, 08h
- mov dx, ADPTR_BD
- out dx, al
- ;
- mov dx, POSBASE + POS0
- in al, dx
- xchg ah, al
- add dx, POS1
- in al, dx
- ; ; Check for our ID
- cmp ax, NI9210_ID
- jne Get_10
- dec bx
- jz Get_15
- Get_10:
- loop Get_05
- lea ax,NiNotFoundMsg
- jmp Get_50
- Get_15: ; found our Adapter
- and cl,7
- mov Ni9210Slot,cl
- ; ; Save Rest of POS data
- mov di,Offset %DGroup:OldPOSData
- mov dx,POSBASE
- mov cx,8
- ;
- %get_dataseg ; ES -> DGroup
- mov es, ax
-
- Get_20: ; Get the POS Data
- insb
-
- inc dx
- loop Get_20
- ;
- ; ; Get Ni9210 I/O Address
- xor ax,ax
- mov al,OldPOSData[POS3]
- shl ax,5
- mov NiPort,ax
- add ax,16 ; set up Interrupt Register address
- mov Ni9210IntPort,ax
- ; ; Get Ni9210 IRQ
- mov bl,OldPOSData[POS2]
- and bx,IRQMASK
- shr bx,1
- mov al,IRQ_TABLE[bx]
- xor ah,ah
- mov NiIRQ,ax
- ; ; Get Memory Address
- xor al,al
- xor bl,bl
- mov ah,OldPOSData[POS5]
- mov bh,OldPOSData[POS4]
- and bx,0E000h
- shl ax,5
- shr bx,3
- or ax,bx
- mov NiMemLoc,ax
-
- ; ; get Memory Size and Bus info
- mov al,OldPosData[POS2] ; This Driver run's as Slave
- test al,BMASEN
- jz Get_30
- ; ; We Don't want Bus Master
- and al,NOT BMASEN
- or al,MEM16K ; We will assume from Master to Slave
- ; ; the static memory is 16K.
- mov dx,POSBASE + POS2
- out dx,al
- %slow
- mov OldPosData[POS2],al
- ; ; Use Static Memory OnBoard
- Get_30: ;
- mov Ni9210Master,FALSE
- and ax,BUSARB
- shr ax,4
- mov Ni9210BusArb,al
- mov NiMemSize,64
- mov Memend,0FFFFh
- test OldPOSData[POS2],MEM16K; Get Memory Size
- jz Get_40
- mov NiMemSize,16
- mov Memend,3FFFh
- ; ; enable the card
- Get_40:
- mov al,OldPosData[POS2]
- or al,CARDENA
- mov dx,POSBASE + POS2
- out dx,al
- %slow
- xor ax,ax ; Success !!!!!
- ; ; disable setup
- Get_50:
- push ax
- mov dx,ADPTR_BD
- xor ax,ax
- out dx,al
- pop ax
-
- %trace_x(I/O base: ,NiPort)
- %trace_x(Int Port: ,Ni9210IntPort)
- %trace_x(Interrupt line: ,NiIRQ)
- %trace_x(Memory base: ,NiMemLoc)
- %trace_x(Memory size (k): ,NiMemSize)
-
- ret
-
- GetConfig endp
-
- ;--------------------------------------------------------------- WriteConfig
- ;
- ; Display the board's configuration parameters (in a micro channel
- ; environment).
- ;
- ;---------------------------------------------------------------------------
-
- ASCII_TABLE db '0123456789ABCDEF'
-
- WriteConfig proc near
- ; ; Set up IRQ Level
- mov dx,NiIRQ
- mov cl,10
- mov di,Offset CIRQL + 2
- pushf
- std
- ;
- Write_10:
- mov ax,dx
- div cl
- mov dl,al
- mov bl,ah
- xor bh, bh
- mov al,ASCII_TABLE[bx]
- stosb
- ;
- mov ax,dx
- div cl
- mov dl,al
- mov bl,ah
- xor bh, bh
- mov al,ASCII_TABLE[bx]
- stosb
- ;
- Write_15:
- ; ; Write I/O Address
- push NiPort
- mov di,Offset CIOl + 3
- mov cl,16
- Write_20:
- pop ax
- xor dx,dx
- or ax,ax
- jz Write_25
- ;
- div cx
- push ax
- and dl,0Fh
- mov bx,dx
- mov al,ASCII_TABLE[bx]
- stosb
- jmp short Write_20
- ;
- Write_25:
- mov di,Offset CMEMl + 3
- push NiMemLoc
- Write_30:
- pop ax
- xor dx,dx
- or ax,ax
- jz Write_35
- ;
- div cx
- push ax
- and dl,0Fh
- mov bx,dx
- mov al,ASCII_TABLE[bx]
- stosb
- jmp short Write_30
- ;
- Write_35:
- popf
- ret
- ;
- WriteConfig endp
-
- end