ne3200.386
Warning: This file has been marked up for HTML
page ,130
;***********************************************************************
; $name: ne3200.386
; $version: 6
; $date_modified: 121898
; $description: NE3200 LAN Driver
; $owner: ODI LAN Driver Manager
; Copyright (c) 1991 - 1998 Novell, Inc. All Rights Reserved.
;
; THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
; USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE AGREEMENT
; ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS THIS WORK.
; PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS TO DEVELOPER A
; ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S SAMPLE CODE IN ITS
; PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE DISTRIBUTION RIGHTS TO MARKET,
; DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE AS A COMPONENT OF DEVELOPER'S
; PRODUCTS. NOVELL SHALL HAVE NO OBLIGATIONS TO DEVELOPER OR DEVELOPER'S
; CUSTOMERS WITH RESPECT TO THIS CODE.
;***********************************************************************
;
; BEGIN_MANUAL_ENTRY( History, NE3200/HISTORY )
;
; Novell NE3200 Driver Code for NetWare 386.
;
; This driver must be loaded after MSM.NLM and ETHERNET.NLM.
;
; Written by: DFS
; Date: January, 1991
;
;***********************************************************************
;
; History Log:
;
; 06-10-91 dfs Modified driver to new MSM spec and enabled interrupts.
;
; 09-03-91 dfs Converted to NLM.(Version 3.20)
;
; 12-16-92 dfs - Rejected bad ECB pointers from Type 4 NLMs.
; - Rejected Packets who's fragment counts exceed 1514.
; - Added 2 second Transmit Timeout.(Version 3.21)
;
; 01-05-93 dfs Added support for DriverEnableInterrupt/DriverDisableInterrupt.
;
; 01-20-93 dfs Limited firmware to 16 fragments instead of 15.
;
; 02-03-93 dfs Removed MSMRescheduleLast from DriverReset.
;
; 02-08-93 dfs Increased RCB's allocated to 16 and table sizes to 32.
;
; 03-30-93 dfs Fixed DriverSend to convert ECB to Physical Address.
; (Version 3.22)
;
; 05-12-93 dfs - Set default back to polling(POLL=0 disables polling).
; - Defaulted board numbers to -1 for clients.
; - Used EtherTSMRcvCompleteStatus instead of EtherTSMRcvComplete.
; - Allowed 2K packets to be received by receive monitor.
; - Fixed receive error status bit bugs.
; - Allowed 14 byte packets to be received.
; (Version 3.23)
;
; 10-05-93 dfs - Added support for DriverSupportsPhysFrags.
; - Stopped checking for Product ID 2(01) at init.
; (Version 3.24)
;
; 02-11-94 akw - Changed the shared interrupt check from the DriverISR routine
; to the DriverDisableInterrupt routine. This will enable the
; the MSM to call other adapters if the interrupt is NOT ours.
; - Changed the # of TX BUFFERS from 10 to 4 in ADAPTER.386.
; - Added support to flag TxTooBig packets and increment counter.
; - Added HSM_SPEC_VERSION string.
; (Version 3.25)
;
; 03-24-94 stc - Changed driver send and send complete code in both the host and
; firmware code to handle fast back-to-back send of more than two
; packets. Changed use of TCB valid mailbox to indicate current
; tx queue index.
; (Version 3.25)
;
; 04-13-94 akw - Changed adapter receive code to not only simply stuff the
; WORD sized board number into the RxECB, but to clear the
; upper WORD as well.
;
; 04-21-94 akw - Added code to SAVE the RProtocolWorkspace field of the
; Rx ECB before handing it to the adapter. Then when the
; adapter is through with it, I restore the field.
;
; 06-28-94 akw - Bumped TOTAL_EISA_SLOTS from 8 to 15 to allow new machines
; with additional slots to run this adapter.
; (Version 3.27)
;
;
; 4 May 1995 15:36 DGM
;
; Added code to DriverDisableInterrupt and DriverEnableInterrupt to
; remove spurious interrupt problem (clearing a pending interrupt
; when enabling adapter). Corrected DriverDisableInterrupt to
; disable the adapter's interrupt even when it's not the adapter's
; as per spec.
;
; Also added code to reject interrupts as ours if we have already
; been disabled. Added code in DriverDisableInterrupt and
; DriverEnableInterrupt to set and clear added InDriverDisable flag.
;
; Altered input parameters to DriverDisableInterrupt to allow for
; 0/1 inputs, also changed initial code in DriverDisableInterrupt
; to first test if we are disabled.
;
; Bumped version number in makefile from 3,2X.
;
; 5 May 1995 8:30 DGM
; Done repair on Adapter firmware, as seeing problems with version 3.50.
; Pulled back orig. code 06-28-94 and re-implemented changes and fixes.
;
; Added code in DriverInit to utilize MSMGetPollSupportLevel which
; returns poll support level. This implies that in SMP OS's the
; NE3200 will operate in Interrupt Only mode. This reduces the
; number of mutexs obtained due to polling routines being continually
; called.
;
; Bumped version number in makefile 3,53
;
; 27 July 1995 4:40 TNL
; Fixed bug in \ introduced in 4-21-94 change.
;
; Changed InDriverInit flag usage and changed name to InDriverReset
; so that DriverShutdown and DriverMulticastChange behave correctly
; when called with DriverReset.
;
; 14 September 1995 11:00 MPK
; Made changes to make code compatable with 3.3 specification.
; Includes changes to DriverConfigTemplate (versions and Scatter
; gap count, Also added changes to initialization, to determine
; BUS by use of NBI calls.
;
; 23 February 1996 11:00 TNL
; Modified DriverInit to call MSMScheduleIntTimeCallback and
; MSMSetHardwareInterrupt in the correct order as described in the
; spec.
;
; 26 February 1996 11:00 TNL
; Modified DriverInit to use NBI calls to get EISA config info.
; See 'if UseNBICalls' code sections.
;
; 05 March 1996 12:00 LON
; Single sourced the NE3200 and the NE3200P. Used existing NE3200
; base and added the Promiscuous code.
;
; 29 March 1996 12:00 TNL
; Modified DriverInit to call MSMReturnDriverResources only when
; appopriate. SPD #121142.
;
; 29 March 1996 1:30 LON
; Removed unneeded Ne3200Promisc. code due to compiler warning. The
; code (offset RBDWrappedCount) was there only for maintaining code.
;
; 26 April 1996 3:30 LON
; Added comments for clarification.
;
; 29 April 1996 6:00 LON
; The SMP driver load/unload test was failing due to a timing window
; where interrupts were still enabled during permanent driver shutdown.
; This allowed the DriverISR routine to allocate RCBs before the
; driver was unloaded (SPD 124131).
;
; 12 June 1996 2:00 LON
; During multiple DriverReset calls, the adapter would appear to not
; reset in fast PCI/EISA boxes. In reality the adapter needed more
; time to initialize after being reset in DriverShutdown. When
; DriverReset detects the adapter failed to reset, the code will now
; call DriverShutdown up to 3 times, giving the adapter another
; chance to reset (SPD 128318).
;
; 11-25-96 PM Modified DriverParameterBlock structure to add the following
; fields immediately after DriverDisableInterrupt field in
; accordance with 3.31 specs. SPD #141183:
; - DriverISR2Ptr - Null entry
; - DriverReserved2 - Null entry
; - HSMSpecVerString - pointer to spec version string
; - DriverPriorityQueuePtr - Null entry
; - DriverDisableInterrupt2Ptr - Null entry
;
; 11-25-96 PM Modified Config Table template to change the following in
; accordance with 3.31 specs. SPD #141183:
; - changed MLIDCFG_MinorVersion from 13 to 14
; - splited up MLIDReserved field that follows
; - MLIDCFG_SGCount into the following fields:
; - MLIDReserved1
; - MLIDPrioritySup
; - MLIDReserved2
; - changed MLIDIOCfgMajorVersion from 00 to 01
;
; 11-25-96 PM Modified DriverReset and DriverShutdown routines to add
; operation scope parameter. SPD #141329
;
; 01-08-97 PM Modified DriverInit routine to point EAX to a valid error
; message before calling MSMPrintSting in case the load fails
; due to some condition.
;
; 07-22-97 JCJ DriverReset and DriverShutdown are modified to update adapter
; about the Shutdown status. SPD #160930
;
; 09-18-97 JCJ If adapter provides 100% filtering of group addresses and
; the TSM does not need to perform any checking, then bits 10&9
; of MLIDFlags should be set. SPD# 165219, 165221.
;
; 12-22-97 LON The AdapterOptionDefinitionStructure had undefined fields (?),
; which can cause abends. All fields are now defined, SPD 174679.
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
name NE3200
title NE3200 LAN Driver (HSM Version)
subttl -- Structures and Equate Values --
page
DEBUG equ 0
CheckTCBs equ 0
CatchIncomplete equ 0
include driver.inc
BusMaster equ -1
UseFastCalls equ -1
AddPolling equ -1
TxQueue equ -1
SupportJabber equ -1
UseNBICalls equ -1
;***********************************************************************\
; *
; NE3200 Equates. *
; *
;***********************************************************************/
;
DEFAULT_TIMEOUT_VALUE equ 2 ; Default Poll timeout.
;***************************************************************\
; *
; Commands to Pass to the NIC's mailbox's. *
; *
;***************************************************************/
;
ADD_MULTICAST_COMMAND equ 1 ; Update Multcast list.
IDLE_COMMAND equ 4 ; Idle the NIC firmware.
;***************************************************************\
; *
; Loop counter equates. *
; *
;***************************************************************/
;
RESET_BASE_COUNT equ 200 ; Speed from slow 386.
;***************************************************************\
; *
; EISA slot equates. *
; *
;***************************************************************/
;
TOTAL_EISA_SLOTS equ 15
MANUFACTURE_CHAR_CODE_1 equ 3Ah ; Computed from the
MANUFACTURE_CHAR_CODE_2 equ 0CCh ; code "NVL 07 01".
PRODUCT_NUMBER_1 equ 07
PRODUCT_NUMBER_2 equ 01
PRODUCT_NUMBER_2b equ 02
;***************************************************************\
; *
; BMIC port structure. *
; *
;***************************************************************/
;
BMICIOStructure struc
ID db 4 dup (?)
Reserved0 db 4 dup (?)
GlobalConfigurationRegister db ?
SystemInterruptMaskControlRegister db ?
Semaphores db 2 dup (?)
LocalDoorbellMaskRegister db ?
LocalDoorbellInterruptStatusRegister db ?
SystemDoorbellMaskRegister db ?
SystemDoorbellInterruptStatusRegister db ?
MailboxRegisters db 16 dup (?)
Reserved1 db 16 dup (?)
BMICIOStructure ends
;***************************************************************\
; *
; Equates and structures used in performing BIOS calls. *
; *
;***************************************************************/
;
ISOLATE_INT_MASK equ 00001111b
EISA_INT_FUNCTION_BIT equ 00000100b
;***************************************************************\
; *
; Miscellaneous driver equates. *
; *
;***************************************************************/
;
TOTAL_RCBS equ 10h
TABLE_SIZE equ 20h
TABLE_MASK equ TABLE_SIZE-1
TCB_TABLE_SIZE equ 256
TOTAL_TCBS equ 128
;***************************************************************\
; *
; ASCII String equates. *
; *
;***************************************************************/
;
BEEP equ 07h ; Bell.
LF equ 0Ah ; Line Feed.
CR equ 0Dh ; Carriage Return.
;***********************************************************************\
; *
; NE3200 Structures. *
; *
;***********************************************************************/
;***************************************************************\
; *
; Start of the Adapter Data Space structure for NE3200. *
; *
;***************************************************************/
;
;JCP
GenericVariableBegin equ offset TotalTxPacketCount ;941130 *Begin*
GenericVariableEnd equ offset CustomVariableCount
CustomVariableBegin equ offset TxRetryFailure
CustomVariableEnd equ offset VectorToTheStrings ;941130 *End*
DriverAdapterDataSpace struc
;
;***************************************************************\
; *
; I/O port register variables. *
; *
;***************************************************************/
;
ResetRegister dd 0 ; Reset Port.
EisaSystemDoorbellEnable dd 0 ; BMIC Doorbell Enable.
EisaSystemDoorbellStatus dd 0 ; BMIC Doorbell Status.
IdleMailbox dd 0 ; Idle adapter Mailbox(1 byte).
UpdateParmMailbox dd 0 ; Update parm mail(1 byte)
UpdateStatMailbox dd 0 ; Update stat mail(1 byte)
TCBValidMailbox dd 0 ; TCB Valid Mail(1 byte port).
;PollingMailbox dd 0 dup (0) ; JCP, 941130.
TCBMailbox dd 0 ; TCB Mailbox(4 byte port).
ParametersMailbox dd 0 ; Parm Mailbox(4 byte port).
;
;--------------------------------------------------------------\
; *
; Adapter Parameter Block. Do not change the order of the *
; following 12 fields. *
; *
;---------------------------------------------------------------/
;
LogicalToPhysicalOffset dd 0
NodeAddressPointer dd 0
BoardNumber8023 dw -1
BoardNumberEII dw -1
BoardNumber8022 dw -1
BoardNumberSNAP dw -1
MaxReceivePacketSize dd 0
GenericStatisticsPointer dd 0
CustomStatisticsCount dw 0
RCBListPointer dd 0
MulticastCount dw 0
MulticastTablePointer dd 0
HostNodeAddress db 6 dup (0)
PromiscuousMode db 0
PollTimeout dw DEFAULT_TIMEOUT_VALUE ;#
GlobalConfigValue db 00001110b
dw ? ; DWORD align
;;IF DEBUG
;;DiagnosticBufferPointer dd 0 ;Diagnostic dump
;;ENDIF
;
; Must be DWORD aligned.
;
;---------------------------------------------------------------\
; *
; Command Parameter storage location. *
; *
;---------------------------------------------------------------/
;
ParameterCommand dd 0 ; Command to NIC.
Parameter1 dd 0 ; Parameter 1.
Parameter2 dd 0 ; Possible Parameter 2.
;
;---------------------------------------------------------------\
; *
; Receive and Transmit Pointers. *
; *
;---------------------------------------------------------------/
;
ReceiveQueueHead dd 0 ; Point to first RCB.
ReceiveQueueTail dd 0 ; Point to last RCB.
NeedRCBCount dd TOTAL_RCBS ; RCB's currently needed.
;
; !!! Important - This list must be dword aligned !!!
; The BMIC locked exchange only works on dword boundaries.
;
; NOTE: AdapterRCBList and HostRCBList are circular queues of pointers which
; point to the exact same ECBs(RCBs). Except AdapterRCBList has the physical
; address of the ECB and HostRCBList has the logical address. When the
; firmware (i.e. Adapter.asm) has received an incoming frame, the firmware
; overwrites the ECB physical address (in AdapterRCBList) with a value of
; Zero. This serves to notify the HSM (Ne3200.386) that the ECB is complete
; and needs to be processed. When the ECB is processed, Ne3200.386
; uses the logical address of the ECB from the HostRCBList.
;
AdapterRCBList dd TABLE_SIZE dup (-1) ; Phys. adr of ECB.
AdapterTCBList dd TCB_TABLE_SIZE dup (-1) ; if TxQueue
;
; HostPWSList1-2 is used for saving/restoring the ECB's RProtocolWorkspace.
HostPWSList1 dd TABLE_SIZE dup (0)
HostPWSList2 dd TABLE_SIZE dup (0)
HostRCBList dd TABLE_SIZE dup (0) ; Logical adr of ECB
HostTCBList dd TCB_TABLE_SIZE dup (0) ; if TxQueue
TxStartList dd TCB_TABLE_SIZE dup (0) ; if TxQueue
TCBQueueHead dd 0 ; if TxQueue
TCBQueueTail dd 0 ; if TxQueue
TCBInProcess dd 0 ; Transmit Sending to NIC.
TxStartTime dd 0 ; Send Time out flag.
UpdateStatCount dd 0 ; Update StatTable every 4 sec.
;
;---------------------------------------------------------------\
; *
; In Driver Procedure flags. *
; *
;---------------------------------------------------------------/
;
InDriverPoll dd 0 ; In Driver Poll flag.
;;TNL InDriverInit dd 0 ; In Driver Init flag.
InDriverReset dd 0 ; In Driver Reset flag.
InDriverDisable dd 0 ; In Driver Disable Flag.
DriverShutdownType dd 0 ; 1=PartialShutdown, 0=Permanent.
;---------------------------------------------------------------\
; *
; Diagnostic structures and variables *
; *
;---------------------------------------------------------------/
;
;;IF DEBUG
;; ALink dd ?
;; AWakeUpDelayAmount dd 10 ;Not changed
;; AWakeUpTime dd ?
;; AProcessToCall dd WriteDiagnosticFile ;Not changed
;; ARTag dd ? ;Not changed
;; AOldLink dd ?
;; DirEntryPtr dd ?
;; DirNumber dd ?
;; FileHandle dd ?
;; BufferAddress dd 0
;; ErrorInstance dd 0
;; FilePathStr db 6,'SYSTEM',12
;; FileName db 'NE32DMPx.xxx'
;;ENDIF
;
;---------------------------------------------------------------\
; *
; Statistics table (This matches the struc in ASTRUC.INC). *
; *
;---------------------------------------------------------------/
;
StatisticsVersion db 03, 00
GenericVariableCount dw (GenericVariableEnd - GenericVariableBegin) / 4
;;;dgm NotSupportedMask0 dd 11110010110010000000000000000011b
NotSupportedMask0 dd 11101010000010000000000000100010b
;GenericVariableBegin db 0 dup (?) ; JCP, 941130.
TotalTxPacketCount dd 0 ; 1 - (Used by MSM)
TotalRxPacketCount dd 0 ; 1 - (Used by MSM)
NoECBAvailableCount dd 0 ; 1 - (Used by MSM)
PacketTxTooBigCount dd 0 ; 0 - Used by driver
PacketTxTooSmallCount dd 0 ; 1 - not used
PacketRxOverflowCount dd 0 ; 0 - Used by driver
PacketRxTooBigCount dd 0 ; 1 - not used
PacketRxTooSmallCount dd 0 ; 0 - not used
PacketTxMiscErrorCount dd 0 ; 0 - used by driver
PacketRxMiscErrorCount dd 0 ; 0 - used by driver
RetryTxCount dd 0 ; 0 - Used by driver
ChecksumErrorCount dd 0 ; 0 - Used by driver
HardwareRxMismatchCount dd 0 ; 1 - (Used by MSM)
TotalTxOKByteCountLow dd 0 ; 0 - Used by MSM
TotalTxOKByteCountHigh dd 0 ; 0 - Used by MSM
TotalRxOKByteCountLow dd 0 ; 0 - Used by MSM
TotalRxOKByteCountHigh dd 0 ; 0 - Used by MSM
TotalGroupAddrTxCount dd 0 ; 0 - Used by MSM
TotalGroupAddrRxCount dd 0 ; 0 - Used by MSM
AdapterResetCount dd 0 ; 0 - Used by HSM driver
AdapterOprTimeStamp dd 0 ; 0 - Used by MSM
QDepth dd 0 ; 0 - Used by MSM
TxOKSingleCollision dd 0 ; 0 - Used by driver
TxOKMultipleCollisions dd 0 ; 0 - Used by driver
TxOKButDeferred dd 0 ; 1 - not used
TxAbortLateCollision dd 0 ; 0 - Used by driver
TxAbortExcessCollisions dd 0 ; 0 - Used by driver
TxAbortCarrierSense dd 0 ; 0 - Used by driver
TxAbortExDeferral dd 0 ; 1 - not used
RxAbortFrameAlignment dd 0 ; 0 - Used by driver
;GenericVariableEnd db 0 dup (?) ; JCP, 941130.
CustomVariableCount dw (CustomVariableEnd - CustomVariableBegin) / 4
;CustomVariableBegin db 0 dup (?) ; JCP, 941130.
TxRetryFailure dd 0 ; Tx Retry failure.
ClearToSend dd 0 ; Tx Clear To Send.
UnderRun dd 0 ; Tx DMA Underrun.
RxDMAOverrun dd 0 ; Rx DMA Overrun.
PacketSlideCount dd 0 ; Rcv frames not matching our
; MC table or node IA adr.
; IFDEF NE3200P
; Wrapping of rcv frame data buffer caused an extra BMIC xfer (3 total).
;
; RBDWrappedCount offset PacketSlideCount
DummyRCBCount dd 0 ; Rx Dummy RCB used.
AdapterReset1 dd 0 ; Adapter Reset
BadFragLengthCount dd 0 ; Mondo Frag length.
PollingTimeout dd 0 ; Poll Timeout.
AdapterDied dd 0 ; Dead hardware.
NumberOfIntsFired dd 0 ; if AddPolling
;CustomVariableEnd db 0 dup (?) ; JCP, 941130.
VectorToTheStrings dd offset DiagnosticsStrings
AlignDEndVA db (4 - offset (AlignDEndVA and 3)) and 3 dup (?) ; Align 4 for MOVSD
DriverAdapterDataSpace ends
;***************************************************************\
;***************************************************************/
PollingMailbox equ offset TCBMailbox ; JCP, 941130.
subttl -- OSDATA Data Segment --
page
assume cs: OSCODE, ds: OSDATA, es: OSDATA, ss: OSDATA
;
;***********************************************************************\
; *
; The following variables are common to the entire driver. *
; *
;***********************************************************************/
;
OSDATA segment rw public 'DATA'
HSMSPEC db 'HSM_SPEC_VERSION: 3.31',0
;
;***************************************************************\
; *
; Statistic Diagnostic Strings. *
; *
;***************************************************************/
;
DiagnosticsStrings dw (EndOfStrings-DiagnosticsStrings)
db 'Transmit Retry Failure:', 0
db 'Tx Clear To Sends Errors:', 0
db 'Tx DMA Underrun Errors:',0
db 'Rx DMA Overrun Errors:', 0
IFNDEF NE3200P
db 'Rx Packet Slide Errors:', 0
ELSE
db '3 BMIC receive transfers:', 0
ENDIF
db 'Rx Dummy RCB Used Errors:', 0
db 'Internal Adapter Reset:', 0
db 'Mondo Fragment Length Errors:', 0
;;if CatchIncomplete
;; db 'Adapter Incomplete Errors:', 0
;; db 'Host Incomplete Error:', 0
;;endif
db 'Polling Timeout:', 0 ;#
db 'Reset Because Hardware Died Errors:', 0
if AddPolling
db 'Number Of Interrupts Fired:', 0
endif
db 0,0
EndOfStrings equ $
;***************************************************************\
; *
; Driver Parameter Block to pass to MSM. *
; *
;***************************************************************/
;
public DriverFirmwareSize
align 4
DriverParameterBlock label dword
DriverParameterSize dd DriverParameterBlockSize
DriverStackPointer dd 0
DriverModuleHandle dd 0
DriverBoardPointer dd 0
DriverAdapterPointer dd 0
DriverConfigTemplatePtr dd DriverConfigTemplate
DriverFirmwareSize dd -1
DriverFirmwareBuffer dd 0
DriverNumKeywords dd 1
DriverKeywordText dd NE3200KeywordText
DriverKeywordTextLen dd NE3200TextLen
DriverProcessKeywordTab dd NE3200ProcessKeywordTab
DriverAdapterDataSpaceSize dd SIZE DriverAdapterDataSpace
DriverAdapterTemplate dd DriverAdapterDataSpaceTemplate
DriverStatisticsTable dd StatisticsVersion
DriverEndOfChainFlag dd 0
DriverSendWantsECBs dd -1 ; want ECBs
DriverMaxMulticast dd 20
DriverNeedsBelow16Meg dd 0
DriverAESPtr dd 0
DriverCallBackPtr dd offset DriverCallBack
DriverISRPtr dd offset DriverISR
DriverMulticastChangePtr dd offset DriverMulticastChange
if AddPolling
DriverPollPtr dd offset DriverPoll
else
DriverPollPtr dd 0
endif
DriverResetPtr dd offset DriverReset
DriverSendPtr dd offset DriverSend
DriverShutdownPtr dd offset DriverShutdown
DriverTxTimeoutPtr dd 0
DriverPromiscuousChangePtr dd offset DriverPromiscuousChange
DriverStatisticsChangePtr dd offset DriverStatisticsChange ; JCP, 941130.
DriverRxLookAheadChangePtr dd 0
DriverManagementPtr dd 0
DriverEnableInterruptPtr dd offset DriverEnableInterrupt
DriverDisableInterruptPtr dd offset DriverDisableInterrupt
DriverISR2Ptr dd 0
DriverReserved2 dd 0
HSMSpecVerString dd offset HSMSPEC
DriverPriorityQueuePtr dd 0
DriverDisableInterrupt2Ptr dd 0
DriverParameterBlockSize equ $ - DriverParameterBlock
;
;***************************************************************\
; *
; Copy of Virtual Adapter Data area to be copied at *
; initialization. *
; *
;***************************************************************/
;
DriverAdapterDataSpaceTemplate DriverAdapterDataSpace <>
;DriverConfigTemplate db 0 dup (?) ; JCP, 941130.
DriverConfigTemplate label byte ; JCP, 941130.
db 'HardwareDriverMLID ' ; [ebx].MLIDCFG_Signature
db 01 ; [ebx].MLIDCFG_MajorVersion
db 14 ; [ebx].MLIDCFG_MinorVersion
db 6 dup (0ffh) ; [ebx].MLIDNodeAddress
if BusMaster
dw 0011000001001001b ; [ebx].MLIDModeFlags
else
dw 0010000001001011b ; [ebx].MLIDModeFlags
endif
dw 0000 ; [ebx].MLIDBoardNumber
dw 0000 ; [ebx].MLIDBoardInstance
dd 00000000 ; [ebx].MLIDMaximumSize
dd 00000000 ; [ebx].MLIDMaxRecvSize
dd 00000000 ; [ebx].MLIDRecvSize
dd 00000000 ; [ebx].MLIDCardName
dd DriverNICShortName ; [ebx].MLIDshortName
dd 00000000 ; [ebx].MLIDFrameType
dw 0000 ; [ebx].MLIDReserved0
dw 0000 ; [ebx].MLIDFrameID
dw 0001 ; [ebx].MLIDTransportTime
dd 000000000 ; [ebx].MLIDRouteHandler
dw 10 ; [ebx].MLIDLineSpeed
dw 0000 ; [ebx].MLIDLookAheadSize
db 17 ; [ebx].MLIDCFG_SGCount
db 00 ; [ebx].MLIDReserved1
dw 0000 ; [ebx].MLIDPrioritySup
dd 00000000 ; [ebx].MLIDReserved2
db 00 ; [ebx].MLIDMajorVersion
db 00 ; [ebx].MLIDMinorVersion
;JCJ: 18-Sep-97 SPD# 165219, 165221
;If adapter provides 100% filtering of group addresses and the TSM does
;not need to perform any checking bits 10&9 of MLIDFlags should be set.
dw 0000011000000000b ; [ebx].MLIDFlags
dw 0005 ; [ebx].MLIDSendRetries
dd 00000000 ; [ebx].MLIDLink
dw IOShareInterrupt0Bit ; [ebx].MLIDSharingFlags
dw 0000 ; [ebx].MLIDSlot
dw 0300h, 30h, 0, 0 ; [ebx].MLIDIOPortsAndLengths
dd 00000000 ; [ebx].MLIDMemoryDecode0
dw 0000 ; [ebx].MLIDLength0
dd 00000000 ; [ebx].MLIDMemoryDecode1
dw 0000 ; [ebx].MLIDLength1
db 0FFh, 0FFh ; [ebx].MLIDInterrupt
db 0FFh, 0FFh ; [ebx].MLIDDMAUsage
dd 00000000 ; [ebx].MLIDResourceTag
dd 00000000 ; [ebx].MLIDConfiguration
dd 00000000 ; [ebx].MLIDCommandString
db 18 dup (0) ; [ebx].MLIDLogicalName
dd 00000000 ; [ebx].MLIDLinearMemory0
dd 00000000 ; [ebx].MLIDLinearMemory1
dw 0000 ; [ebx].MLIDChannelNumber
dd 00000000 ; [ebx].MLIDBusTag
db 01 ; [ebx].MLIDIOCfgMajorVersion
db 00 ; [ebx].MLIDIOCfgMinorVersion
IFNDEF NE3200P
Message DriverNICShortName, 'NE3200'
ELSE
Message DriverNICShortName, 'NE3200P'
ENDIF
if UseNBICalls
;
;***********************************************************************\
; *
; Parameters required by NBI Calls *
; *
;***********************************************************************/
;
CFG_BUFFER_SIZE equ 320 ; Size of EISA cfg block
ProductID db MANUFACTURE_CHAR_CODE_1, MANUFACTURE_CHAR_CODE_2
db PRODUCT_NUMBER_1, PRODUCT_NUMBER_2
ConfigBuffer db CFG_BUFFER_SIZE dup (0)
endif
;***************************************************************\
; *
; Parameters required by ParseDriverParameters. *
; *
;***************************************************************/
;
SlotsWithMyBoardCount dd 0
SlotsWithMyBoard dd TOTAL_EISA_SLOTS dup (0)
AdapterOptions AdapterOptionDefinitionStructure < SlotsWithMyBoardCount,0,0,0,0,0,0,0,0,0,0,0,0,0 >
CountForLoop dd 600000 ; Force to minimum.
CountForReset dd RESET_BASE_COUNT * 5 ; Force to minimum.
CommonMaximumSize dd 0 ; Max Packet size.
EISAInterruptField db 0
;
;***************************************************************\
; *
; Top Of Physical Memory variables. *
; *
;***************************************************************/
;
SystemMemoryMap dd (2 * 8) dup (0)
if CheckTCBs
TopOfPhysicalMemory dd 0
endif
;
;***************************************************************\
; *
; Custom Keyword information. *
; *
;***************************************************************/
;
; Poll = <TIMEOUT> or 0 to disable polling.
;
PollText db 'POLL' ; POLL = keyword.
PollTextLen equ $-PollText OR T_HEX_NUMBER
dd 0 ; Minimum.
dd 0ffffh ; Maximum.
NE3200KeywordText dd PollText ; First Keyword.
NE3200TextLen dd PollTextLen ; First Keywords length.
NE3200ProcessKeywordTab dd PollTimeoutRoutine
PollingTimeoutValue dd 0
;
;***************************************************************\
; *
; Hardware Initialization Error Messages. *
; *
;***************************************************************/
;
NoBoardsFound db 050, 00, 'The board cannot be found.', CR, LF, 0
EisaBiosReadErrorMsg db 234, 00, 'The board cannot read the configuration.', CR, LF, 0
NoIntMsg db 235, 00, 'No interrupt was selected. The board must be reconfigured.', CR, LF, 0
NoFirstRCBMsg db 236, 00, "No RCBs are available for the board to initialize.", CR, LF, 0
FirmwareInitErrorMsg db 237, 00, 'The firmware cannot be initialized.', CR, LF, 0
StaticMemoryErrorMsg db 051, 00, "Board RAM failed the memory test.", CR, LF, 0
RomErrorMsg db 241, 00, "The board's ROM has checksum errors.", CR, LF, 0
FirmwareLoadErrorMsg db 238, 00, 'The firmware cannot be started.', CR, LF, 0
ParameterPassErrorMsg db 070, 00, 'The board has failed.', CR, LF, 0
if BusMaster
LevelErrorMsg db 150, 00, 'EtherTSM.NLM Assembly HSM Interface Level is %d.', CR, LF
db 'This HSM needs Level 200.', CR, LF, 0
endif
if AddPolling
InterruptOnlyMsg db 'Interrupt Only Mode.', CR, LF, 0
PollingMsg db 'Polling With Interrupt Backup and %dns Poll Timeout Mode.', CR, LF, 0
endif
IF DEBUG
DiagAllocMemErrorMsg db 052, 00, "Unable to allocate 64k diagnostic buffer.", CR, LF, 0
ENDIF
InstanceMappingErrorMsg db 230, 00, "Failed to retrieve information associated with the specified Instance Number.", CR
CardConfigErrorMsg db 200, 00, "Can not read the configuration parameters for the given adapter.", CR, LF, 0
InterruptSetMsg db 150, 00, "The Hardware Interrupt can not be set.", CR, LF, 0
EnablePollingErrorMsg db 100, 00, "The polling process can not be enabled.", CR, LF, 0
ParameteridentifyErrorMsg db 250, 00, "Can not read bus specific information represented by the given identifier.", CR, LF, 0
ScheduleIntErrorMsg db 230, 00, "Can not schedule an interrupt time callback with the OS.", CR, LF, 0
;
;***************************************************************\
; *
; Run-time Alert Error Messages. *
; *
;***************************************************************/
;
BadECBMessage db "An NLM sent an ECB pointer(%x) that was out of range to a DMA adapter.", CR, LF, 0
OSDATA ends
subttl -- DriverChangeMulticast --
page
OSCODE segment er public 'CODE'
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverMulticastChange, NE3200/API/MULTI )
;
; Name: DriverMulticastChange
;
; Description: This routine will modify the NIC's multicast registers to
; enable it to receive the multicast addresses listed in
; the multicast table. Each entry in the multicast table is as
; follows:
;
; bytes 0-5 = Multicast Address.
; bytes 6-7 = Entry used(Non zero if used).
;
; On Entry: EAX N/A
; EBX N/A
; ECX # of Entries in Table( 0 if empty )
; EDX N/A
; EBP @ Adapter Data Space
; ESI @ Multicast Table
; EDI N/A
;
; Note: Interrupts are in any state.
;
; On Return: EAX Destroyed
; EBX Preserved
; ECX Destroyed
; EDX Destroyed
; EBP Preserved
; ESI Preserved
; EDI Preserved
;
; Flags:
;
; Note: Interrupts preserved.
;
; Remarks: This routine is called by the ethernet media module.
; (e.g. EtherTSMUpdateMulticast which our DriverReset calls).
; It can be called at process or interrupt time.
;
; See Also: ETHERTSM\EtherTSMAddMulticastAddress
; ETHERTSM\EtherTSMDeleteMulticastAddress
; ETHERTSM\EtherTSMUpdateMulticast
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
align 16
DriverMulticastChange proc
if BusMaster
mov [ebp].MulticastCount, cx ; Save cnt in Parm blk.
mov eax, esi ; EAX -> MulticastTbl.
call MSMGetPhysical ; Convert to phys.
mov [ebp].MulticastTablePointer, eax ; Store phys addr.
else
add esi, LogicalToPhysical ; Convert to phys.
mov [ebp].MulticastTablePointer, esi ; Save in adapter
mov [ebp].MulticastCount, cx ; parameter block.
endif
;;TNL cmp [ebp].InDriverInit, 0 ; In Driver Init?
cmp [ebp].InDriverReset, 0 ; In Driver Reset?
jnz short DriverMulticastExit ; Exit if so.
mov edx, [ebp].UpdateParmMailbox ; EDX = Parm Update.
mov ecx, CountForLoop ; Set Loop counter.
WaitForMailBoxToClear:
in al, dx ; AL = Parm Update.
or al, al ; Cleared by adapter?
jz short ParameterMailboxClear ; Jump if so.
dec ecx ; Loop.
jnz WaitForMailBoxToClear
ParameterMailboxClear:
inc al ; Set AL = 1.
out dx, al ; Set Update port.
DriverMulticastExit:
ret ; Exit.
DriverMulticastChange endp
subttl -- DriverPromiscuousChange --
page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverPromiscuousChange, NE2000/API/PROMISCU )
;
; Name: DriverPromiscuousChange
;
; Description: This routine will enable/disable the Promiscuous Mode.
;
; On Entry: EAX N/A
; EBX N/A
; ECX 0 to disable the Promiscuous mode
; If non zero, bit 3 is set if Remote Multicast Frames are to be received.
; EDX N/A
; EBP @ Adapter Data Space
; ESI @ Multicast Table
; EDI N/A
;
; Note: Interrupts are in any state.
;
; On Return: EAX Destroyed
; EBX Preserved
; ECX Destroyed
; EDX Destroyed
; EBP Preserved
; ESI Destroyed
; EDI Destroyed
;
; Flags:
;
; Note: Interrupts preserved.
;
; Remarks: This routine is called by the ethernet media module,
; (e.g. EtherTSMUpdateMulticast which our DriverReset calls).
; It can be called at process or interrupt time.
;
; See Also: ETHERTSM\EtherTSMPromiscuousChange
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
align 16
DriverPromiscuousChange proc
mov [ebp].PromiscuousMode, cl ; Store mode.
;;TNL cmp [ebp].InDriverInit, 0 ;; In Driver Init?
cmp [ebp].InDriverReset, 0 ; In Driver Reset?
jnz short DriverPromiscuousExit ; Exit if so.
mov edx, [ebp].UpdateParmMailbox ; EDX == Parm Update.
mov ecx, CountForLoop ; Set Loop counter.
PromWaitForMailBoxToClear:
in al, dx ; AL = Parm Update.
or al, al ; Cleared by adapter?
jz short ParameterMailboxReady ; Jump if so.
dec ecx ; Loop.
jnz PromWaitForMailBoxToClear
ParameterMailboxReady:
inc al ; Set AL = 1.
out dx, al ; Set Update port.
DriverPromiscuousExit:
ret
DriverPromiscuousChange endp
subttl -- DriverStatisticsChange --
page
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverStatisticsChange, NE3200/API/PROMISCU )
;
; Name: DriverStatisticsChange
;
; Description: This routine will update the statistics table.
;
; On Entry: EAX N/A
; EBX @ Frame Data Space
; ECX N/A
; EDX N/A
; EBP @ Adapter Data Space
; ESI N/A
; EDI N/A
;
; Note: Interrupts are disable.
;
; On Return: EAX Destroyed
; EBX Preserved
; ECX Destroyed
; EDX Destroyed
; EBP Preserved
; ESI Destroyed
; EDI Destroyed
;
; Flags:
;
; Note: Interrupts preserved.
;
; Remarks: This routine is called by the media specific module.
; It can be called at process or interrupt time.
; Added by JCP, 941130.
;
; See Also: MSM\MSMGetMLIDStatistics
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
align 16
DriverStatisticsChange proc
mov edx, [ebp].UpdateStatMailbox ; EDX -> Stat Update.
mov al, 1 ; Set AL = 1.
out dx, al ; Write to port(Notify firmware).
call MSMGetMicroTimer ; EAX = current count.
mov edx, eax ; Save the old count.
neg edx ; Negate so later add does subt.
WaitForTxOrRxToFinish: ; Give firmware time to update cntrs.
call MSMGetMicroTimer ; EAX = New current count.
add eax, edx ; Subtract old time from new.
cmp eax, 16000 ; Have 1.6 millisec passed?
jb WaitForTxOrRxToFinish ; Jump if below 1.6 msec.
mov [ebp].UpdateStatCount, 0 ; Reset Counter. JCP, 941205.
ret
DriverStatisticsChange endp
subttl -- DriverSend --
page
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverSend, NE3200/API/SEND )
;
; Name: DriverSend
;
; Description: This routine passes the ECB to the adapter for transmission.
; The driver will place the physical address of the TCB into
; the NE3200's send ECB mailbox and informs the NE3200 that it
; is there. It will then return until DriverISR finds that the
; adapter has DMA'd it into its own buffer.
;
; On Entry: EAX N/A
; EBX @ Frame Data Space
; ECX Padded Packet Length
; EDX N/A
; EBP @ Adapter Data Space
; ESI @ Logical address of ECB (i.e TCB)
; EDI @ Physical address of ECB (i.e TCB)
;
; Note: Interrupts are disabled.
;
; On Return: EAX Destroyed
; EBX Preserved
; ECX Destroyed
; EDX Destroyed
; EBP Preserved
; ESI Destroyed
; EDI Destroyed
;
; Flags:
;
; Note: Interrupts disabled.
;
; Remarks: This routine is called by the MSM media module.
; It is called at process or interrupt time.
;
; See Also: ETHERTSM\EtherTSMDriverSend
; ETHERTSM\MediaSendRaw8023
; ETHERTSM\MediaSendEthernetII
; ETHERTSM\MediaSend8022Over8023
; ETHERTSM\MediaSend8022Snap
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
public DriverSend
align 16
DriverSend proc
if TxQueue
mov ecx, [ebp].TCBQueueTail ; EAX -> Next spot in list.
;; STC 3/24/94
;; mov edx, [ebp].TCBMailbox ; DX -> NIC's TCB port.
mov [ebp].HostTCBList[ecx*4], esi ; Save TCB into list.
ife BusMaster
add esi, LogicalToPhysical ; Convert to physical addr.
endif
if CheckTCBs
cmp esi, TopOfPhysicalMemory ; ECB out of range?
ja short DriverSendError ; Jump if so.
mov eax, [esi].RFragmentCount
lea edi, [esi].RPacketOffset
CheckTCBLoop1:
test dword ptr [edi], 80000000h ; Fragment out of range?
jne short DriverSendError ; Jump if so.
add edi, 8
dec eax
jne CheckTCBLoop1
endif
if BusMaster
mov [ebp].AdapterTCBList[ecx*4], edi
else
mov [ebp].AdapterTCBList[ecx*4], esi
endif
;; STC 3/24/94
;; mov al, 1 ; Set Tx waiting bit.
;; dec edx ; Place it into Tx State box.
;; out dx, al
mov edx, [ebp].TCBValidMailbox ; DX -> NIC's TCB Valid port.
mov al, cl ; Give new queue index to firmware.
inc al ; Note TCB queue size is 256.
out dx, al
MSMGetCurrentTime
mov [ebp].TxStartList[ecx*4], eax ; Save Start time.
inc cl ; Bump index(Index is 0 - 255).
mov [ebp].TCBQueueTail, ecx ; Save new TCB index.
cmp [ebp].MSMTxFreeCount, TOTAL_TCBS-1 ; Transmits pending?
jb short DriverSendComplete ; Jump if not.
DriverSendExit:
ret ; Exit.
DriverSendComplete:
mov eax, [ebp].TCBQueueHead ; EAX -> Head of TCB list.
cmp dword ptr [ebp].AdapterTCBList[eax*4], -1 ; Done?
jne DriverSendExit ; Jump if not.
mov esi, [ebp].HostTCBList[eax*4] ; ESI = RCB.
inc al ; Bump index.
mov [ebp].TCBQueueHead, eax ; Save new index.
inc [ebp].MSMTxFreeCount ; We now can send another ECB.
jmp EtherTSMFastSendComplete ; Return the TCB.
;ret
else
mov eax, esi ; EAX -> Logical TCB.
if BusMaster
add eax, LogicalToPhysical ; EAX -> Physical TCB.
endif
if CheckTCBs
cmp eax, TopOfPhysicalMemory ; ECB out of range?
ja short DriverSendError ; Jump if so.
mov ecx, [esi].RFragmentCount
lea edi, [esi].RPacketOffset
CheckTCBLoop2:
test dword ptr [edi], 80000000h ; Fragment out of range?
jne short DriverSendError ; Jump if so.
add edi, 8
dec ecx
jne CheckTCBLoop2
endif
mov edx, [ebp].TCBMailbox ; DX -> NIC's TCB port.
out dx, eax ; Load it into TCB mailbox.
mov al, 1 ; Set Tx waiting bit.
dec edx ; Place it into Tx State box.
out dx, al
mov [ebp].TCBInProcess, esi ; Save TCB until BMIC is done.
MSMGetCurrentTime
mov [ebp].TxStartTime, eax ; Save start time.
ret
endif
if CheckTCBs
DriverSendError:
push esi
mov ecx, esi ; ECX -> ECB.
lea esi, BadECBMessage ; ESI -> Error Message.
call MSMAlertFatal
pop esi ; ESI -> ECB.
inc [ebp].MSMTxFreeCount ; We now can send another ECB.
jmp EtherTSMFastSendComplete ; Give ECB back and return.
endif
DriverSend endp
subttl -- DriverISR --
page
;
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverISR, NE3200/API/ISR )
;
; Name: DriverISR
;
; Description: This routine handles packet reception and transmit complete
; interrupts.
;
; On Entry: EAX N/A
; EBX N/A
; ECX N/A
; EDX N/A
; EBP @ Adapter Data Space
; ESI N/A
; EDI N/A
;
; Note: Interrupts are disabled.
;
; On Return: EAX Destroyed
; EBX Destroyed
; ECX Destroyed
; EDX Destroyed
; EBP Destroyed
; ESI Destroyed
; EDI Destroyed
;
; Flags:
;
; Note: Interrupts disabled.
;
; Remarks: This routine is called by the MSM.
; It is called at interrupt time.
;
; See Also: MSM\MSMInterruptProcedure
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
public DriverISR
align 16
DriverISR proc
if AddPolling
inc [ebp].NumberOfIntsFired ; Inc stat counter.
cmp [ebp].InDriverPoll, 0 ; In DriverPoll?
jne DriverISRExit ; Exit if so.
endif
;---------------------------------------------------------------\
; *
; Check for Completed RCBs. When the firmware is done receiving *
; a frame, it overwrites the physical address of the ECB *
; (in AdapterRCBList) with a value of Zero. *
; *
;---------------------------------------------------------------/
DriverISRCheckRCBLoop:
mov eax, [ebp].ReceiveQueueHead ; EAX -> Head of RCB list.
;; mov ecx, [ebp].AdapterRCBList[eax*4]; ECX = Size field.
;;if SupportJabber
;; cmp ecx, 2048+14
;;else
;; cmp ecx, 1514 ; Filled in by adapter?
;;endif
;; cmp ecx, 2048+14
cmp [ebp].AdapterRCBList[eax*4], 0 ; Did adapter copy a new rcv
; frame to us for processing?
ja DriverISRCheckNeedCount ; Jump if no.
mov [ebp].AdapterRCBList[eax*4], -1 ; Indicate entry is unused.
mov esi, [ebp].HostRCBList[eax*4] ; ESI = RCB.
mov edx, eax ; Save ReceiveQueueHead
inc eax ; Bump index.
and al, TABLE_MASK
mov [ebp].ReceiveQueueHead, eax ; Save new Head of RCB list.
inc [ebp].NeedRCBCount ; Inc Get RCB flag for alloc.
ife BusMaster
mov eax, PhysicalToLogical
add [esi].RPacketOffset, eax
endif
if CatchIncomplete
cmp dword ptr [esi].RImmediateAddress, 0
je short IPXLengthOK
cmp dword ptr [esi].RProtocolID+0, 0 ; IPX PID?
jne short IPXLengthOK ; Jump if not.
mov eax, dword ptr [esi].RProtocolID+2 ; EAX = PID.
or eax, eax ; IPX 802.3?
je short CheckIPXLength ; Jump if so.
cmp eax, 37810000h ; IPX EII or SNAP?
je short CheckIPXLength ; Jump if so.
cmp eax, 0e0000000h ; IPX 802.2?
jne short IPXLengthOK ; Jump if not.
CheckIPXLength:
mov edi, [esi].RPacketOffset
movzx eax, word ptr [edi+2]
xchg al, ah ; EAX = IPX length.
cmp eax, [esi].RPacketLength ; Greater than ECB?
jbe short IPXLengthOK ; Jump if not.
inc [ebp].HostIncompleteCount ; Inc statistic.
mov ebx, [ebp].MSMDefaultVirtualBoard
mov eax, [ebp].HostPWSList1[edx*4] ; Restore first dword
mov [esi].RProtocolWorkspace+0, eax ; Put it back here.
mov eax, [ebp].HostPWSList2[edx*4] ; Restore second dword
mov [esi].RProtocolWorkspace+4, eax ; Put it back here.
MSMReturnRCB
mov eax, OP_SCOPE_ADAPTER
call DriverReset ; Reset Adapter.
jmp DriverISRExit ; Go exit.
IPXLengthOK:
endif
;---------------------------------------------------------------\
; *
; NOTE: EtherTSMFastRcvCompleteStatus requires: *
; ECX = packet size (including header), *
; EAX = error status (if any). *
; *
;---------------------------------------------------------------/
mov eax, dword ptr [esi].RProtocolWorkspace ; EAX = Error Status.
mov ecx, dword ptr [esi].RProtocolWorkspace+4 ; ECX = Packet Size.
mov ebx, [ebp].HostPWSList1[edx*4] ; Restore first dword
mov dword ptr [esi].RProtocolWorkspace+0, ebx ; Put it back here.
mov ebx, [ebp].HostPWSList2[edx*4] ; Restore second dword
mov dword ptr [esi].RProtocolWorkspace+4, ebx ; Put it back here.
if UseFastCalls
push ebp
call EtherTSMFastRcvCompleteStatus ; Give RCB to protocol stack.
pop ebp
jmp DriverISRCheckRCBLoop
else
push offset DriverISRCheckRCBLoop ; Jump back to loop.
jmp EtherTSMRcvCompleteStatus ; Give RCB to LSL.
endif
;-------------------------------------------------------------------\
; *
; Allocate more RCB's. At initialization NeedRCBCount starts at 16h.*
; *
;-------------------------------------------------------------------/
;
DriverISRCheckNeedCount:
mov ecx, [ebp].NeedRCBCount ; ECX = RCB's needed.
or ecx, ecx ; Any RCB's needed?
jz short DriverISRCheckTCB ; Jump if not.
DriverISRGetRCBLoop:
mov esi, CommonMaximumSize ; ESI = Max packet Size.
call MSMAllocateRCB ; Attempt to get an RCB.
jnz short DriverISRCheckTCB ; Jump if unsuccessful.
;---------------------------------------------------------------\
; *
; MSMAllocateRCB zeroed out the RProtocolWorkspace field. *
; ESI = Logical address of ECB. *
; EDI = Physical address of ECB. (for BusMaster systems) *
; *
;---------------------------------------------------------------/
dec [ebp].NeedRCBCount ; Dec need counter.
mov eax, [ebp].ReceiveQueueTail ; EAX -> Next spot in list.
mov edx, dword ptr [esi].RProtocolWorkspace+0 ; Get first dword
mov dword ptr [ebp].HostPWSList1[eax*4], edx ; Save first dword
mov edx, dword ptr [esi].RProtocolWorkspace+4 ; Get 2nd dword
mov dword ptr [ebp].HostPWSList2[eax*4], edx ; Save 2nd dword
mov [ebp].HostRCBList[eax*4], esi ; Save RCB into list.
if BusMaster
mov [ebp].AdapterRCBList[eax*4], edi
else
add esi, LogicalToPhysical ; Convert to physical addr.
mov [ebp].AdapterRCBList[eax*4], esi
endif
inc eax ; Bump index.
and al, TABLE_MASK ; Perform Modulo operation.
mov [ebp].ReceiveQueueTail, eax ; Save new index.
dec ecx ; More RCB's needed?
jnz DriverISRGetRCBLoop ; Jump if so and loop.
DriverISRCheckTCB:
;
;---------------------------------------------------------------\
; *
; Check if Transmit is finished. *
; *
;---------------------------------------------------------------/
;
if TxQueue
cmp [ebp].MSMTxFreeCount, TOTAL_TCBS ; Transmits pending?
je short DriverISRGetNextSend ; Jump if not.
mov eax, [ebp].TCBQueueHead ; EAX -> Head of TCB list.
cmp dword ptr [ebp].AdapterTCBList[eax*4], -1 ; Done?
jne short DriverISRGetNextSend ; Jump if not.
mov esi, [ebp].HostTCBList[eax*4] ; ESI = RCB.
inc al ; Bump index.
mov [ebp].TCBQueueHead, eax ; Save new index.
inc [ebp].MSMTxFreeCount ; We now can send another ECB.
if UseFastCalls
push ebp
call EtherTSMFastSendComplete ; Return the TCB.
pop ebp
else
call EtherTSMSendComplete
endif
jmp DriverISRCheckTCB
DriverISRGetNextSend:
test [ebp].MSMStatusFlags, TXQUEUED
je short DriverISRExit
;---------------------------------------------------------------\
; *
; Call TSM for any more ECBs to send. *
; EDI = ESI = ECB address. *
; *
;---------------------------------------------------------------/
call EtherTSMGetNextSend ; Another send waiting?
jnz short DriverISRExit ; Jump if not.
mov ecx, [ebp].TCBQueueTail ; ECX -> Next spot in list.
mov [ebp].HostTCBList[ecx*4], esi ; Save TCB into list.
ife BusMaster
add esi, LogicalToPhysical ; Convert to physical addr.
endif
if CheckTCBs
cmp esi, TopOfPhysicalMemory ; ECB out of range?
ja short DriverISRBadTCB ; Jump if so.
mov eax, [esi].RFragmentCount
lea edi, [esi].RPacketOffset
CheckTCBLoop3:
test dword ptr [edi], 80000000h ; Fragment out of range?
jne short DriverISRBadTCB
add edi, 8
dec eax
jne CheckTCBLoop3
endif
if BusMaster
mov [ebp].AdapterTCBList[ecx*4], edi
else
mov [ebp].AdapterTCBList[ecx*4], esi
endif
;; STC 3/24/94
;; mov edx, [ebp].TCBMailbox ; DX -> NIC's TCB port.
;; mov al, 1 ; Set Tx waiting bit.
;; dec edx ; Place it into Tx State box.
;; out dx, al
mov edx, [ebp].TCBValidMailbox ; DX -> NIC's TCB Valid port.
mov al, cl ; Give new queue index to firmware.
inc al
out dx, al
MSMGetCurrentTime
mov [ebp].TxStartList[ecx*4], eax ; Save Start time.
inc cl ; Bump index.
mov [ebp].TCBQueueTail, ecx ; Save new index.
jmp DriverISRGetNextSend
else
cmp [ebp].TCBInProcess, 0 ; TCB In Process?
je short DriverISRExit ; Jump if not.
mov edx, [ebp].TCBValidMailbox ; EDX = NIC's TCB status port.
in al, dx ; AL = Status.
or al, al ; Is it finished?
jnz short DriverISRExit ; Jump if not.
mov esi, [ebp].TCBInProcess ; ESI -> TCB to return.
mov [ebp].TCBInProcess, 0 ; NIC is done with TCB.
inc [ebp].MSMTxFreeCount ; We now can send another ECB.
if UseFastCalls
push ebp
call EtherTSMFastSendComplete ; Return TCB.
pop ebp
else
call EtherTSMSendComplete ; Return TCB.
endif
DriverISRGetNextSend:
test [ebp].MSMStatusFlags, TXQUEUED
je short DriverISRExit
call EtherTSMGetNextSend ; Another send waiting?
jnz short DriverISRExit ; Jump if not.
mov edx, [ebp].TCBMailbox ; DX -> NIC's TCB port.
mov eax, esi ; EAX -> Logical TCB.
if BusMaster
add eax, LogicalToPhysical ; EAX -> Physical TCB.
endif
if CheckTCBs
cmp eax, TopOfPhysicalMemory ; ECB out of range?
ja short DriverISRBadTCB ; Jump if so.
mov eax, [esi].RFragmentCount
lea edi, [esi].RPacketOffset
CheckTCBLoop4:
cmp dword ptr [edi], 80000000h ; Fragment out of range?
jne short DriverISRBadTCB
add edi, 8
dec eax
jne CheckTCBLoop4
endif
out dx, eax ; Load it into TCB mailbox.
mov al, 1 ; Set Tx waiting bit.
dec edx ; Place it into Tx State box.
out dx, al
mov [ebp].TCBInProcess, esi ; Save TCB until BMIC is done.
MSMGetCurrentTime
mov [ebp].TxStartTime, eax ; Save start time.
endif
;
;---------------------------------------------------------------\
; *
; Exit the ISR. *
; *
;---------------------------------------------------------------/
;
DriverISRExit:
if not UseFastCalls
MSMServiceEvents
endif
xor eax, eax ; Interrupt Serviced return.
ret
if CheckTCBs
DriverISRBadTCB:
push esi
mov ecx, esi ; ECX -> ECB.
lea esi, BadECBMessage ; ESI -> Error Message.
call MSMAlertFatal
pop esi ; ESI -> ECB.
call EtherTSMFastSendComplete ; Give ECB back and return.
inc [ebp].MSMTxFreeCount ; We now can send another ECB.
jmp DriverISRGetNextSend ; Check for another ECB.
endif
DriverISR endp
If AddPolling
;
;***********************************************************************\
; *
; DriverPoll Procedure *
; *
;***********************************************************************/
;
public DriverPoll
align 16
DriverPoll proc
mov [ebp].InDriverPoll, 1 ; Set flag.
mov edx, [ebp].PollingMailbox ;#
xor al, al ;#
out dx, al ; Zero out the I/O port.
;---------------------------------------------------------------\
; *
; Polling - Check for finished RCBs. *
; The adapter indicates a new rcv frame is ready by zeroing *
; out the corresponding ptr in the AdapterRCBList. *
; *
;---------------------------------------------------------------/
DriverPollCheckRCBLoop:
mov eax, [ebp].ReceiveQueueHead ; EAX -> Head of RCB list.
;; mov ecx, [ebp].AdapterRCBList[eax*4]; ECX = Size field.
;;if SupportJabber
;; cmp ecx, 2048+14
;;else
;; cmp ecx, 1514 ; Filled in by adapter?
;;endif
cmp [ebp].AdapterRCBList[eax*4], 0 ; Did adapter copy a new rcv
; frame to us for processing?
ja short DriverPollCheckNeedCount ; Jump if no.
mov [ebp].AdapterRCBList[eax*4], -1 ; Indicate entry's available.
mov esi, [ebp].HostRCBList[eax*4] ; ESI = RCB.
mov edx, eax ; Save ReceiveQueueHead
inc eax ; Bump index.
and al, TABLE_MASK
mov [ebp].ReceiveQueueHead, eax ; Save new Head of RCB list.
inc [ebp].NeedRCBCount ; Inc Get RCB flag for alloc.
ife BusMaster
mov eax, PhysicalToLogical
add [esi].RPacketOffset, eax
endif
if CatchIncomplete
cmp dword ptr [esi].RImmediateAddress, 0
je short PollIPXLengthOK
cmp dword ptr [esi].RProtocolID+0, 0 ; IPX PID?
jne short PollIPXLengthOK ; Jump if not.
mov eax, dword ptr [esi].RProtocolID+2 ; EAX = PID.
or eax, eax ; IPX 802.3?
je short PollCheckIPXLength ; Jump if so.
cmp eax, 37810000h ; IPX EII or SNAP?
je short PollCheckIPXLength ; Jump if so.
cmp eax, 0e0000000h ; IPX 802.2?
jne short PollIPXLengthOK ; Jump if not.
PollCheckIPXLength:
mov edi, [esi].RPacketOffset
movzx eax, word ptr [edi+2]
xchg al, ah ; EAX = IPX length.
cmp eax, [esi].RPacketLength ; Greater than ECB?
jbe short PollIPXLengthOK ; Jump if not.
;; inc [ebp].HostIncompleteCount ; Inc stat.
;; mov ebx, [ebp].MSMDefaultVirtualBoard
;; MSMReturnRCB
;; mov eax, OP_SCOPE_ADAPTER
;; call DriverReset ; Reset Adapter.
;; jmp DriverPollExit ; Get out.
PollIPXLengthOK:
endif
mov eax, dword ptr [esi].RProtocolWorkspace ; EAX = Error Status.
mov ecx, dword ptr [esi].RProtocolWorkspace+4 ; ECX = Packet Size.
mov ebx, [ebp].HostPWSList1[edx*4] ; Restore first dword
mov dword ptr [esi].RProtocolWorkspace+0, ebx ; Put it back here.
mov ebx, [ebp].HostPWSList2[edx*4] ; Restore second dword
mov dword ptr [esi].RProtocolWorkspace+4, ebx ; Put it back here.
if UseFastCalls
push ebp
call EtherTSMFastRcvCompleteStatus ; Give RCB to protocol stack.
pop ebp
jmp DriverPollCheckRCBLoop
else
push offset DriverPollCheckRCBLoop ; Jump back to loop.
jmp EtherTSMRcvCompleteStatus ; Give RCB to LSL.
endif
;---------------------------------------------------------------\
; *
; Polling - Allocate more RCB's. *
; *
;---------------------------------------------------------------/
align 16
DriverPollCheckNeedCount:
mov ecx, [ebp].NeedRCBCount ; ECX = RCB's needed.
or ecx, ecx ; Any RCB' needed?
jz short DriverPollCheckTCB ; Jump if not.
DriverPollGetRCBLoop:
mov esi, CommonMaximumSize ; ESI = Max packet Size.
call MSMAllocateRCB ; Attempt to get an RCB.
jnz short DriverPollCheckTCB ; Jump if unsuccessful.
;---------------------------------------------------------------\
; *
; MSMAllocateRCB zeroed out the RProtocolWorkspace field. *
; ESI = Logical address of ECB. *
; EDI = Physical address of ECB. (for BusMaster systems) *
; *
;---------------------------------------------------------------/
mov eax, [ebp].ReceiveQueueTail ; EAX -> Next spot in list.
dec [ebp].NeedRCBCount ; Dec need counter.
mov edx, dword ptr [esi].RProtocolWorkspace+0 ; Get first dword
mov dword ptr [ebp].HostPWSList1[eax*4], edx ; Save first dword
mov edx, dword ptr [esi].RProtocolWorkspace+4 ; Get 2nd dword
mov dword ptr [ebp].HostPWSList2[eax*4], edx ; Save 2nd dword
mov [ebp].HostRCBList[eax*4], esi
if BusMaster
mov [ebp].AdapterRCBList[eax*4], edi; Save RCB into list.
else
add esi, LogicalToPhysical ; Convert to physical addr.
mov [ebp].AdapterRCBList[eax*4], esi; Save RCB into list.
endif
inc eax ; Bump index.
and al, TABLE_MASK
mov [ebp].ReceiveQueueTail, eax ; Save new index.
dec ecx ; More RCB's needed?
jnz DriverPollGetRCBLoop ; Jump if so.
DriverPollCheckTCB:
;---------------------------------------------------------------\
; *
; *
; Polling - Check if Transmit is finished. *
; *
; When polling we want to make sure that the polling loop length*
; is the same whether or not we have an outstanding transmit. *
; Otherwise, the server utilization number will be messed up. *
; *
;---------------------------------------------------------------/
if TxQueue
mov eax, [ebp].TCBQueueHead ; EAX -> Head of TCB list.
mov ecx, [ebp].MSMTxFreeCount
sub ecx, TOTAL_TCBS - 1 ; ECX=1 if no xmits, <= 0 if
; has outstanding transmits.
add ecx, [ebp].AdapterTCBList[eax*4]; Test for -1.
jge short DriverPollGetNextSend ; If -1 and ECX not 1 then continue.
mov esi, [ebp].HostTCBList[eax*4] ; ESI = RCB.
inc al ; Bump index.
mov [ebp].TCBQueueHead, eax ; Save new index.
inc [ebp].MSMTxFreeCount ; We now can send another ECB.
if UseFastCalls
push ebp
call EtherTSMFastSendComplete ; Return the TCB.
pop ebp
else
call EtherTSMSendComplete
endif
jmp DriverPollCheckTCB ; Loop.
DriverPollGetNextSend:
test [ebp].MSMStatusFlags, TXQUEUED
je short DriverPollExit
;---------------------------------------------------------------\
; *
; Call TSM for any more ECBs to send. *
; EDI = ESI = ECB address. *
; *
;---------------------------------------------------------------/
call EtherTSMGetNextSend ; Another send waiting?
jnz short DriverPollExit ; Jump if not.
mov ecx, [ebp].TCBQueueTail ; ECX -> Next spot in list.
mov [ebp].HostTCBList[ecx*4], esi ; Save TCB into list.
ife BusMaster
add esi, LogicalToPhysical ; Convert to physical addr.
endif
if CheckTCBs
cmp esi, TopOfPhysicalMemory ; ECB out of range?
ja short DriverPollBadTCB ; Jump if so.
mov eax, [esi].RFragmentCount
lea edi, [esi].RPacketOffset
CheckTCBLoop5:
test dword ptr [edi], 80000000h ; Fragment out of range?
ja short DriverPollBadTCB
add edi, 8
dec eax
jne CheckTCBLoop5
endif
if BusMaster
mov [ebp].AdapterTCBList[ecx*4], edi
else
mov [ebp].AdapterTCBList[ecx*4], esi
endif
;; STC 3/24/94
;; mov edx, [ebp].TCBMailbox ; DX -> NIC's TCB port.
;; mov al, 1 ; Set Tx waiting bit.
;; dec edx ; Place it into Tx State box.
;; out dx, al
mov edx, [ebp].TCBValidMailbox ; DX -> NIC's TCB Valid port.
mov al, cl ; Give new queue index to firmware.
inc al
out dx, al
MSMGetCurrentTime
mov [ebp].TxStartList[ecx*4], eax ; Save Start time.
inc cl ; Bump index.
mov [ebp].TCBQueueTail, ecx ; Save new index.
jmp DriverPollGetNextSend
else
cmp [ebp].TCBInProcess, 0 ; TCB In Process?
je short DriverPollExit ; Jump if not.
mov edx, [ebp].TCBValidMailbox ; EDX = NIC's TCB status port.
in al, dx ; AL = Status.
or al, al ; Is it finished?
jnz short DriverPollExit ; Jump if not.
mov esi, [ebp].TCBInProcess ; ESI -> TCB to return.
mov [ebp].TCBInProcess, 0 ; NIC is done with TCB.
inc [ebp].MSMTxFreeCount ; We now can send another ECB.
if UseFastCalls
push ebp
call EtherTSMFastSendComplete ; Return TCB.
pop ebp
else
call EtherTSMSendComplete ; Return TCB.
endif
DriverPollGetNextSend:
test [ebp].MSMStatusFlags, TXQUEUED
je short DriverPollExit
call EtherTSMGetNextSend ; Another send waiting?
jnz short DriverPollExit ; Jump if not.
mov edx, [ebp].TCBMailbox ; DX -> NIC's TCB port.
mov eax, esi ; EAX -> Logical TCB.
ife BusMaster
add eax, LogicalToPhysical ; EAX -> Physical TCB.
endif
if CheckTCBs
cmp eax, TopOfPhysicalMemory ; ECB out of range?
ja short DriverPollBadTCB ; Jump if so.
mov eax, [esi].RFragmentCount
lea edi, [esi].RPacketOffset
CheckTCBLoop6:
test dword ptr [edi], 80000000h ; Fragment out of range?
jne short DriverPollBadTCB
add edi, 8
dec eax
jne CheckTCBLoop6
endif
out dx, eax ; Load it into TCB mailbox.
mov al, 1 ; Set Tx waiting bit.
dec edx ; Place it into Tx State box.
out dx, al
mov [ebp].TCBInProcess, esi ; Save TCB until BMIC is done.
MSMGetCurrentTime
mov [ebp].TxStartTime, eax ; Save start time.
endif
;---------------------------------------------------------------\
; *
; Exit DriverPoll. *
; *
;---------------------------------------------------------------/
DriverPollExit:
if not UseFastCalls
MSMServiceEvents
endif
mov [ebp].InDriverPoll, 0
ret ; Exit.
if CheckTCBs
DriverPollBadTCB:
push esi
mov ecx, esi ; ECX -> ECB.
lea esi, BadECBMessage ; ESI -> Error Message.
call MSMAlertFatal
pop esi ; ESI -> ECB.
call EtherTSMFastSendComplete ; Give ECB back and return.
inc [ebp].MSMTxFreeCount ; We now can send another ECB.
jmp DriverPollGetNextSend
endif
DriverPoll endp
endif
subttl -- DriverDisableInterrupt --
page
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverDisableInterrupt, NE3200/API/DISINT )
;
; Name: DriverDisableInterrupt
;
; Description: This routine will disable the adapters ability to
; interrupt the host.
;
; On Entry: EAX 1 If we want to know if it's our Interrupt
; 0 just disable the adapter.
;
; EBX N/A
; ECX N/A
; EDX N/A
; EBP @ Adapter Data Space
; ESI N/A
; EDI N/A
;
; Note: Interrupts are disabled.
;
; On Return: EAX Destroyed
; EBX Preserved
; ECX Preserved
; EDX Destroyed
; EBP Preserved
; ESI Preserved
; EDI Preserved
;
; Flags:
;
; Note: Interrupts disabled.
;
; Remarks: This routine is called by the MSM.
;
; See Also: DriverEnableInterrupt
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
align 16
public DriverDisableInterrupt
DriverDisableInterrupt proc
cmp [ebp].InDriverDisable, 0 ; Already disabled interrupts?
jnz short DriverDisableNotOurs ; Jump if yes.
or eax, eax ; Is EAX a Zero?
jz short DriverDisableNicOnly ; Jmp if so (Disable NIC only).
; o/p don't care.
mov edx, [ebp].EisaSystemDoorbellStatus ; Check for interrupt.
in al, dx
test al, 1 ; Our interrupt?
jz short DriverDisableNicOnly ; Jump if not.
;---------------------------------------------------------------\
; *
; Disable NE3200's interrupt mechanism. *
; *
;---------------------------------------------------------------/
mov edx, [ebp].EisaSystemDoorbellEnable
xor al, al ; Disable doorbell.
out dx, al
mov [ebp].InDriverDisable, 01 ; Set flag we're disabled.
mov eax, 1
mov edx, [ebp].EisaSystemDoorbellStatus
out dx, al ; Reset our Status port.
xor eax, eax ; Indicate our interrupt.
ret ; Exit.
;---------------------------------------------------------------\
; *
; Disable NE3200's interrupt mechanism only. *
; *
;---------------------------------------------------------------/
DriverDisableNicOnly:
mov [ebp].InDriverDisable, 01 ; Set flag we're disabled.
xor eax, eax
mov edx, [ebp].EisaSystemDoorbellEnable
out dx, al ; Disable doorbell.
DriverDisableNotOurs:
or eax, 1 ; Int not ours flag.
ret ; Exit.
DriverDisableInterrupt endp
subttl -- DriverEnableInterrupt --
page
;***************************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverEnableInterrupt, NE3200/API/ENINT )
;
; Name: DriverEnableInterrupt
;
; Description: This routine will enable the adapters ability to
; interrupt the host.
;
; On Entry: EAX N/A
; EBX N/A
; ECX N/A
; EDX N/A
; EBP @ Adapter Data Space
; ESI N/A
; EDI N/A
;
; Note: Interrupts are disabled.
;
; On Return: EAX Destroyed
; EBX Preserved
; ECX Preserved
; EDX Destroyed
; EBP Preserved
; ESI Preserved
; EDI Preserved
;
; Flags:
;
; Note: Interrupts disabled.
;
; Remarks: This routine is called by the MSM.
;
; See Also: DriverDisableInterrupt
;
; END_MANUAL_ENTRY
;
;***************************************************************************/
align 16
public DriverEnableInterrupt
DriverEnableInterrupt proc
;---------------------------------------------------------------------------\
; *
; If we have an interrupt pending, this output to EisaSystemDoorbellStatus *
; will clear it, which will cause a spurious interrupt. *
; *
; It's best to just re-enable the adapters interrupts and if one is pending *
; then we will re-enter our interrupt routine to deal with it and not miss *
; it and hence no spurious interrupts. *
; *
;---------------------------------------------------------------------------/
mov [ebp].InDriverDisable, 0 ; Clear disable flag.
mov edx, [ebp].EisaSystemDoorbellEnable
mov eax, 1
out dx, al ; Enable doorbell.
ret ; Exit.
DriverEnableInterrupt endp
subttl -- DriverCallBack --
page
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverCallBack, NE3200/API/CALLBACK )
;
; Name: DriverCallBack
;
; Description: This routine may be used to schedule events at time intervals
; specified by the driver. Common uses are for transmit dead-
; man timers on ethernet or reading statistics from the adapter
; on token ring. This driver is using it to inform the adapter
; to upload its statistics every 4 seconds. It is recommended
; that this call be used over DriverAES and DriverPoll.
;
; On Entry: EAX N/A
; EBX @ Frame Data Space
; ECX N/A
; EDX N/A
; EBP @ Adapter Data Space
; ESI N/A
; EDI N/A
;
; Note: Interrupts are disabled.
;
; On Return: EAX Destroyed
; EBX Preserved
; ECX Preserved
; EDX Destroyed
; EBP Preserved
; ESI Preserved
; EDI Preserved
;
; Flags:
;
; Note: Interrupts preserved.
;
; Remarks: This routine is called by the MSM.
; After this call returns, the MSM will schedule another
; call back.
; It is called at interrupt time.
;
; See Also: MSM\MSMCallBackProcedure
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
align 16
DriverCallBack proc
;;dgm mov edx, [ebp].UpdateStatMailbox ; EDX -> Stat update
;;dgm mov al, 1 ; Set it.
;;dgm out dx, al
if TxQueue
cmp [ebp].MSMTxFreeCount, TOTAL_TCBS ; Transmit outstanding?
else
cmp [ebp].MSMTxFreeCount, 1 ; Transmit outstanding?
endif
je short DriverCallBackExit ; Jump if not.
MSMGetCurrentTime ; EAX = Current Time.
if TxQueue
mov ecx, [ebp].TCBQueueHead ; ECX -> Head of TCB list.
cmp [ebp].AdapterTCBList[ecx*4], -1
je short DriverCallBackExit
sub eax, [ebp].TxStartList[ecx*4] ; EAX = Send Time.
else
sub eax, [ebp].TxStartTime ; EAX = Send Time.
endif
; cmp eax, 18 * 4 ; Timeout?
cmp eax, 18 * 9 ; Half second.
jae short DriverCallBackReset ; Jump if so.
DriverCallBackExit: ;;dgm - JCP modified
cmp [ebp].UpdateStatCount, 8 ; 4 seconds yet ?
jae DriverCallBackFinalExit ; Jump if yes.
mov [ebp].UpdateStatCount, 0 ;Reset Counter.
mov edx, [ebp].UpdateStatMailbox ;EDX -> Stat update
mov al, 1 ;Set it.
out dx, al
DriverCallBackFinalExit:
ret ; Done.
DriverCallBackReset:
inc [ebp].AdapterDied ; Bump statistic.
mov ebx, [ebp].MSMDefaultVirtualBoard
mov eax, OP_SCOPE_ADAPTER
jmp DriverReset ; Reset.
DriverCallBack endp
subttl -- DriverInit --
page
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverInit, NE3200/API/INIT )
;
; Name: DriverInit
;
; Description: This routine will call EtherTSMRegisterHSM,
; MSMParseDriverParameters, MSMRegisterHardwareOptions,
; MSMSetHardwareInterrupt, MSMRegisterMLID, initialize
; variables in the Adapter Data Space and reset/initialize
; the card by calling DriverReset.
;
; On Entry: EAX N/A
; EBX N/A
; ECX N/A
; EDX N/A
; EBP N/A
; ESI N/A
; EDI N/A
;
; Note: Interrupts are enabled.
;
; On Return: EAX 0 if successful(otherwise it points to error message)
; EBX Preserved
; ECX Destroyed
; EDX Destroyed
; EBP Preserved
; ESI Preserved
; EDI Preserved
;
; Flags:
;
; Note: Interrupts preserved.
;
; Remarks: This routine is called by the OS at load time.
; It is called at process time.
;
; See Also: MSM\MSMParseDriverParameters
; MSM\MSMRegisterHardwareOptions
; MSM\MSMSetHardwareInterrupts
; MSM\MSMRegisterMLID
; MSM\MSMScheduleIntTimeCallBack
; MSM\MSMScheduleAESCallBack
; MSM\MSMEnablePolling
; DriverReset
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
align 16
public DriverInit
DriverInit proc
CPush
mov PollingTimeoutValue, DEFAULT_TIMEOUT_VALUE ;#
;---------------------------------------------------------------\
; *
; Fill in Driver Parameter Block fields. *
; *
;---------------------------------------------------------------/
mov DriverStackPointer, esp ; Fill in stack ->.
lea esi, DriverParameterBlock ; ESI -> Parm block.
call EtherTSMRegisterHSM ; Get EBX ->Frame Data Space
; (or Config table).
jnz DriverInitError ; Jump if error.
;
; 09/13/95 MPK Spec 3.3 changes
;
push ebx ; Save EBX we will need it.
mov esi,-1 ; Set Parameter for call.
S33_Bus_Scan:
call MSMScanBusInfo ; Find out about Bus.
cmp eax,ODI_NBI_SUCCESSFUL ; Are we done?
jne S33_Bus_Scan_Done ; Yes, exit.
cmp ecx,ODI_BUSTYPE_EISA ; Is this EISA? (NE3200 EISA only).
jne S33_Bus_Scan ; No, then keep looking.
pop ebx ; Yes, then place tag in param table.
mov [ebx].MLIDBusTag,edx ; Tag in EDX goes into location.
push ebx ; Keep BX straight.
jmp S33_Bus_Scan ; Keep cycling (for completeness).
S33_Bus_Scan_Done:
pop ebx ; Now we can restore EBX for good.
;
; 09/13/95 MPK Spec 3.3 changes End
if BusMaster
call EtherTSMGetASMHSMIFLevel
cmp eax, 220
mov ecx, eax
lea eax, LevelErrorMsg
jb DriverInitResetError ; Jump if wrong TSM level.
endif
;---------------------------------------------------------------\
; *
; Calculate Loop Counter based on Processor Speed. *
; *
;---------------------------------------------------------------/
MSMGetProcessorSpeedRating ; EAX = Processor Speed.
cmp eax, 200 ; Slow machine?
jb short InitLoopCountSet ; Jump if so.
xor edx, edx ; Clear high dword of dividend.
mov ecx, 100 ; Divisor = 100.
idiv ecx ; EAX = Speed / 100.
mov esi, eax ; Save quotient.
mov ecx, 30000h ; EAX =
imul eax, ecx ; (Speed/100) * 30000h.
mov CountForLoop, eax ; Save it.
mov eax, esi ; EAX = Speed / 100.
mov ecx, RESET_BASE_COUNT ; EAX =
imul eax, ecx ; (Speed/100) * 200.
mov CountForReset, eax ; Save it.
InitLoopCountSet:
;---------------------------------------------------------------\
; *
; Save Maximum Packet size for Allocating RCB's at run time. *
; *
;---------------------------------------------------------------/
mov eax, [ebx].MLIDMaximumSize ; EAX = LSL's Max Packet Size.
mov CommonMaximumSize, eax ; Save it.
;---------------------------------------------------------------\
; *
; Find all of the Ne3200 NICs in the machine. *
; *
;---------------------------------------------------------------/
if UseNBICalls
mov esi, -1 ; ESI = ScanSequence
mov ebx, offset ProductID ; EBX -> ProductID
mov byte ptr [ebx+3], PRODUCT_NUMBER_2 ; Set product ID
xor edx, edx ; Start with zero cards found.
ScanSlotsForID1:
push edx ; Save card count
mov eax, 4 ; EAX = ProductIDLength
mov ecx, ODI_BUSTYPE_EISA ; ECX = BusType
call MSMSearchAdapter ; Let MSM scan for us
pop edx ; Get card count back
jnz short ScanNextID ; Jump if no more cards found
mov SlotsWithMyBoard[edx * 4], ecx ; Save slot # (HIN) into table.
inc edx ; Count it
jmp short ScanSlotsForID1 ; Keep looking.
ScanNextID:
mov esi, -1 ; ESI = ScanSequence
mov ebx, offset ProductID ; EBX -> ProductID
mov byte ptr [ebx+3], PRODUCT_NUMBER_2b ; Set next product ID
ScanSlotsForID2:
push edx ; Save card count
mov eax, 4 ; EAX = ProductIDLength
mov ecx, ODI_BUSTYPE_EISA ; ECX = BusType
call MSMSearchAdapter ; Let MSM scan for us
pop edx ; Get card count back
jnz short FinishScanSlots ; Jump if no more cards found
mov SlotsWithMyBoard[edx * 4], ecx ; Save slot # (HIN) into table.
inc edx ; Count it
jmp short ScanSlotsForID2 ; Keep looking.
else
xor ecx, ecx ; Clear slot count.
xor esi, esi ; Clear slot number.
mov edx, 0C80h ; Start with slot zero.
ScanSlots:
inc esi ; Update slot number.
cmp esi, TOTAL_EISA_SLOTS ; Are we done?
ja short FinishScanSlots ; Jump if so.
and dx, 0FFF0h ; Roll back to first id.
add dx, 1000h ; DX = xC80h.
in al, dx ; Get first ID byte.
cmp al, MANUFACTURE_CHAR_CODE_1 ; Is this our ID?
jne ScanSlots ; If not goto next slot.
inc dx ; Move to next ID port.
in al, dx ; Get next ID byte.
cmp al, MANUFACTURE_CHAR_CODE_2 ; Is this our ID?
jne ScanSlots ; If not goto next slot.
inc dx ; Move to next id port.
in al, dx ; Get next ID byte.
cmp al, PRODUCT_NUMBER_1 ; Is this our ID?
jne ScanSlots ; If not goto next slot.
mov SlotsWithMyBoard[ecx * 4], esi ; Save slot number in table.
inc ecx ; Update total slots.
jmp ScanSlots ; Continue search.
endif
FinishScanSlots:
if UseNBICalls
mov ecx, edx
endif
or ecx, ecx ; Any cards found?
lea eax, NoBoardsFound ; EAX -> Error message.
jz DriverInitResetError ; Jump if not.
mov SlotsWithMyBoardCount, ecx ; Save number of NE3200's.
;---------------------------------------------------------------\
; *
; EBX -> Frame Data Space(Config Table). *
; Let MSM Parse the command line. *
; *
;---------------------------------------------------------------/
mov eax, NeedsIOSlotBit OR CAN_SET_NODE_ADDRESS
lea ecx, AdapterOptions
call MSMParseDriverParameters
jnz DriverInitError ; Jump if error.
;---------------------------------------------------------------\
; *
; Store base I/O port based on physical slot. *
; *
;---------------------------------------------------------------/
if UseNBICalls
push ebx ; Save cfg table ptr.
movzx edx, [ebx].MLIDSlot ; EDX = Slot (HIN) to use.
call MSMGetInstanceNumberMapping ; Get UniqueID/BusTag back.
push eax
lea eax, InstanceMappingErrorMsg
jnz DriverInitErrorPopEBX ; Jump if error.
pop eax
; EBX = UniqueID
; ECX = BusTag
mov eax, 1 ; EAX = Parameter count
mov edi, offset ConfigBuffer ; EDI = &Buffer
call MSMGetUniqueIdentifierParameters ; Get Physical slot#
lea eax, ParameteridentifyErrorMsg
jnz DriverInitErrorPopEBX ; Jump if error.
mov eax, [edi] ; EAX = Physical slot
mov edx, ebx ; EDX = UniqueID
pop ebx ; EBX = Cfg Table
else
movzx eax, [ebx].MLIDSlot ; EAX = Slot choosen by user.
endif
shl eax, 12 ; EAX = Slot index.
add eax, 0C80h ; EAX = index + EISA port.
mov [ebx].MLIDIOPortsAndLengths, ax ; Store in config table.
;---------------------------------------------------------------\
; *
; Read configuration from EISA BIOS. *
; *
;---------------------------------------------------------------/
if UseNBICalls ; ECX = BusTag
push ebx ; Save Cfg Table ptr
mov ebx, edx ; EBX = UniqueID
mov edi, offset ConfigBuffer ; EDI -> ConfigBuffer
mov esi, CFG_BUFFER_SIZE ; ESI = ConfigBufferSize
xor eax, eax ; EAX = EISA Cfg Block #
ReadConfigBlockLoop:
push eax ; Save Block #
call MSMGetCardConfigInfo
lea eax, CardConfigErrorMsg
jnz DriverInitErrorPopEBX ; Jump if error
pop eax ; Get Block #
inc eax ; EAX = Next Block #
test byte ptr [edi + 22h], EISA_INT_FUNCTION_BIT ; Valid Int?
jz short ReadConfigBlockLoop ; Jump if not.
mov dl, byte ptr [edi + 0b2h] ; EDX = possible int.
mov EISAInterruptField, dl
and dl, ISOLATE_INT_MASK ; Mask off interrupt field.
jz short ReadConfigBlockLoop ; Jump out if not.
pop ebx ; Get Cfg table back
else
movzx ecx, [ebx].MLIDSlot ; Start with Block 0.
ReadConfigBlockLoop:
call MSMReadEISAConfig ; Get config block.
lea eax, NoIntMsg ; EAX -> Error Message.
jne DriverInitResetError
inc ch ; CH = Next Block.
test byte ptr [esi + 22h], EISA_INT_FUNCTION_BIT ; Valid Int?
jz short ReadConfigBlockLoop ; Jump if not.
mov dl, byte ptr [esi + 0b2h] ; EDX = possible int.
mov EISAInterruptField, dl
and dl, ISOLATE_INT_MASK ; Mask off interrupt field.
jz short ReadConfigBlockLoop ; Jump out if not.
endif
mov [ebx].MLIDInterrupt, dl ; Copy int to config table.
;---------------------------------------------------------------\
; *
; Let MSM Register the hardware options with the OS. *
; *
;---------------------------------------------------------------/
call MSMRegisterHardwareOptions
cmp eax, 1 ; Error Registering?
ja DriverInitError ; Jump if so.
je DriverInitExit ; Skip if new frame.
;---------------------------------------------------------------\
; *
; If debugging then allocate a 64K diagnostic buffer *
; *
;---------------------------------------------------------------/
IF DEBUG
extrn MSMInitAlloc: near
mov eax, 1000h ; Allocate 4K.
call MSMInitAlloc
mov [ebp].BufferAddress, eax
or eax, eax
lea eax, DiagAllocMemErrorMsg
jz DriverInitResetError
sub eax, eax
mov edi, [ebp].BufferAddress
mov ecx, 1000h/4
rep stosd
ENDIF
;---------------------------------------------------------------\
; *
; EBX -> Frame Data Space(Config Table). *
; EBP -> Adapter Data Space. *
; *
;---------------------------------------------------------------/
test EISAInterruptField, 01000000b ; Shared ints?
je short DriverInitSetInterrupt ; Jump if not.
and [ebp].GlobalConfigValue, 11110111b
DriverInitSetInterrupt:
cmp [ebx].MLIDInterrupt, 0ffh ; Interrupt enabled?
lea eax, NoIntMsg
jz DriverInitResetError
;---------------------------------------------------------------\
; *
; Set up I/O port variables. *
; *
;---------------------------------------------------------------/
DriverInitSetupIOPorts:
movzx edx, [ebx].MLIDIOPortsAndLengths
lea eax, [edx].SystemDoorbellMaskRegister
mov [ebp].EisaSystemDoorbellEnable, eax
lea eax, [edx].SystemDoorbellInterruptStatusRegister
mov [ebp].EisaSystemDoorbellStatus, eax
lea eax, [edx].MailboxRegisters ; EAX -> Mailbox Base.
mov [ebp].IdleMailbox, eax ; Save Abend port.
inc eax
mov [ebp].UpdateParmMailbox, eax ; Save Parm Update port.
inc eax
mov [ebp].UpdateStatMailbox, eax ; Save Stat Update port.
mov [ebp].UpdateStatCount, 0 ;Reset Counter. JCP, 941205.
inc eax
mov [ebp].TCBValidMailbox, eax ; Save TCB Valid Register.
inc eax
mov [ebp].TCBMailbox, eax ; Save TCB Register.
add eax, 8
mov [ebp].ParametersMailbox, eax ; Save Parm Register.
;; movzx eax, [ebx].MLIDSlot ; EAX = Slot number.
;; shl eax, 12 ; EAX = X000 port.
movzx eax, [ebx].MLIDIOPortsAndLengths ; EAX = XC80 port.
sub eax, 0C80h ; EAX = X000 port.
mov [ebp].ResetRegister, eax ; Save it for later.
;;TNL mov [ebp].InDriverInit, -1 ; Set InDriverInit flag.
if TxQueue
mov [ebp].MSMTxFreeCount, TOTAL_TCBS
endif
if AddPolling
mov eax, PollingTimeoutValue ; Save timeout into adapter
mov [ebp].PollTimeout, ax ; parameter block.
call MSMGetPollSupportLevel ; Check if OS supports polling.
cmp eax, 1 ; Is Polling supported?
ja short HavePollingSupport ; Jump if yes.
mov [ebp].PollTimeout, 0 ; Force Interrupt only.
HavePollingSupport:
endif
;---------------------------------------------------------------\
; *
; Reset the adapter. *
; *
;---------------------------------------------------------------/
mov eax, OP_SCOPE_ADAPTER
call DriverReset ; Initialize NIC.
;;TNL mov [ebp].InDriverInit, 0 ; Clear InDriverInit flag.
mov [ebp].AdapterResetCount, 0 ; DriverReset incremented it.
jnz DriverInitResetError ; Exit if error reseting.
call MSMSetHardwareInterrupt
jnz DriverInitError ; Jump if error.
if CheckTCBs
;---------------------------------------------------------------\
; *
; Calculate Top of memory to protect ourselves from 4.x *
; Transmit ECBs that may have logical addresses we can't handle.*
; *
;---------------------------------------------------------------/
push 8 ; Max Buffer entries.
push offset SystemMemoryMap ; Buffer for OS to fill in.
call GetSystemMemoryMap
add esp, (2 * 4)
cmp eax, 8
ja ScheduleCallBack ; Can't determine it.
lea esi, SystemMemoryMap
MemoryMapLoop:
mov edi, [esi+0] ; edi -> Offset.
add edi, [esi+4] ; edi -> Offset + length.
cmp edi, TopOfPhysicalMemory ; Below known Max?
jb short MemoryMapNext ; Jump if so.
mov TopOfPhysicalMemory, edi ; Save current Max.
MemoryMapNext:
add esi, 8
dec eax
jne short MemoryMapLoop
endif
;---------------------------------------------------------------\
; *
; Let MSM enable Call back and exit DriverInit. *
; *
;---------------------------------------------------------------/
if AddPolling
cmp [ebp].PollTimeout, 0 ;# Enable Polling?
je short DriverRegisterMLID ;# Jump if not.
call MSMEnablePolling
lea eax, EnablePollingErrorMsg
jnz DriverInitError
DriverRegisterMLID: ;#
endif
call MSMRegisterMLID ; Register MLID.
jnz DriverInitError ; Jump if error.
ScheduleCallBack: ; JCP, 941205 *Begin*
;; mov eax, (18 * 4) ; Schedule call back in 4 secs.
mov eax, 18 * 9 ; Schedule callback in 1/2 second.
; JCP, 941205 *End*
call MSMScheduleIntTimeCallBack
lea eax, ScheduleIntErrorMsg
jnz DriverInitError ; Jump if error.
if AddPolling
movzx eax, [ebp].PollTimeout ;# EAX = cycles
mov ecx, 400 ;# 400ns per cycle.
mul ecx ;#
mov ecx, eax ;# ECX = timeout in ns.
lea esi, InterruptOnlyMsg ;# ESI -> Interrupt Message.
or ecx, ecx ;# Polling enabled?
je short PrintModeMessage ;# Jump if not.
lea esi, PollingMsg ;# ESI -> Polling Message.
PrintModeMessage: ;#
call MSMPrintString ;#
endif
DriverInitExit:
;---------------------------------------------------------------\
; *
; Determine frame type and send Parm Block to adapter. *
; *
;---------------------------------------------------------------/
cmp [ebx].MLIDFrameID, 5 ; Raw 802.3?
jnz short PostCheckEII ; Jump if not.
movzx eax, [ebx].MLIDBoardNumber ; EAX = Board Number.
mov [ebp].BoardNumber8023, ax ; Save it.
jmp short PostUpdateAdapter
PostCheckEII:
cmp [ebx].MLIDFrameID, 2 ; Ethernet II?
jnz short PostCheck8022 ; Jump if not.
movzx eax, [ebx].MLIDBoardNumber ; EAX = Board Number.
mov [ebp].BoardNumberEII, ax ; Save it.
jmp short PostUpdateAdapter
PostCheck8022:
cmp [ebx].MLIDFrameID, 3 ; 802.2?
jnz short PostMustBeSNAP ; Jump if not.
movzx eax, [ebx].MLIDBoardNumber ; EAX = Board Number.
mov [ebp].BoardNumber8022, ax ; Save it.
jmp short PostUpdateAdapter
PostMustBeSNAP:
movzx eax, [ebx].MLIDBoardNumber ; EAX = Board Number.
mov [ebp].BoardNumberSNAP, ax ; Save it.
PostUpdateAdapter:
mov edx, [ebp].UpdateParmMailbox ; EDX = Parm Update
mov ecx, CountForLoop ; Set Loop counter.
;---------------------------------------------------------------\
; *
; If any previous command is pending then wait before we *
; notify the Adapter of a Parameter Update command. *
; *
;---------------------------------------------------------------/
WaitForUpdateMailBoxToClear:
in al, dx ; AL = Parm Update.
or al, al ; Cleared by adapter?
jz short UpdateParmMailboxClear ; Jump if so.
dec ecx ; Loop.
jnz WaitForUpdateMailBoxToClear
UpdateParmMailboxClear:
inc al ; Set AL = 1.
out dx, al ; Write to Update port.
xor eax, eax
CPop
ret ; Exit.
DriverInitErrorPopEBX:
pop ebx
DriverInitResetError:
push eax ; Save error message.
push ecx
call MSMReturnDriverResources ; Return resources.
pop ecx
pop eax ; EAX -> error message.
DriverInitError:
mov esi, eax ; ESI -> error message.
call MSMPrintString ; Display message.
CPop
or eax, 1 ; Do not load error code.
ret
DriverInit endp
subttl -- DriverReset --
page
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverReset, NE3200/API/RESET )
;
; Name: DriverReset
;
; Description: This routine will reset and initialize the NIC.
;
; On Entry: EAX set to OP_SCOPE_ADAPTER if the adapter specified by EBP
; is to be reset. Otherwise set to OP_SCOPE_LOGICAL_BOARD
; which indicates that only the logical board specified
; by EBX is to be reset.
; EBX @ Frame Data Space
; ECX N/A
; EDX N/A
; EBP @ Adapter Data Space
; ESI N/A
; EDI N/A
;
; Note: Interrupts are disabled.
;
; On Return: EAX 0 if successful(otherwise points to error message)
; EBX Preserved
; ECX Destroyed
; EDX Destroyed
; EBP Preserved
; ESI Destroyed
; EDI Destroyed
;
; Flags:
;
; Note: Interrupts disabled.
;
; Remarks: This routine is called by the MSM media module and by
; DriverInit. It is called at process time.
;
; See Also: ETHERTSM\EtherTSMReset
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
align 16
public DriverReset
DriverReset proc near
mov [ebp].InDriverReset, 1 ; Set InDriverReset flag.
cmp eax, OP_SCOPE_ADAPTER
je DriverResetRetry
;------------------------------------------------------------------------
;JCJ 11-July-1997 Now the scope is OP_SCOPE_LOGICAL_BOARD.
; This reset means a previously shutdown logical board to
; be activated. spd #160930
;------------------------------------------------------------------------
movzx eax, [ebx].MLIDBoardNumber ;Board Number in eax
call SetDriverDataBoardNumber ;Set the board number in
;adapter space
;------------------------------------------------------------------------
;Now inform the firmware that driver parameters have been updated.
Call UpdateDriverData
jz DoneWithUpdation
jmp DriverResetErrorExit
DoneWithUpdation:
jmp DontEnableInterrupts ;Exit reset.
;JCJ END SPD #160930
;End of DriverReset with OP_SCOPE_LOGICAL_BOARD
;Begin DriverReset with OP_SCOPE_ADAPTER
DriverResetRetry:
;---------------------------------------------------------------\
; *
; Call DriverShutdown to reset NIC (uses the ResetRegister port)*
; and return any TCB's or RCB's that the Driver has acquired. *
; *
;---------------------------------------------------------------/
mov ecx, 1
mov eax, OP_SCOPE_ADAPTER ; Indicate partial shutdown.
call DriverShutdown ; Reset NIC card.
;---------------------------------------------------------------\
; *
; Attempt to allocate the first RCB. *
; *
;---------------------------------------------------------------/
inc [ebp].AdapterResetCount ; Increment Reset stats.
xor eax, eax ; EAX = index reg(init to 0).
mov [ebp].ReceiveQueueHead, eax ; Init head and queue.
mov [ebp].ReceiveQueueTail, eax
mov esi, CommonMaximumSize ; ESI = Max Packet Size.
call MSMAllocateRCB ; Allocate a RCB (ESI= @ECB).
jnz short WaitOnFirmware ; Jump if no RCB.
dec [ebp].NeedRCBCount
xor eax, eax ; Start with index of Zero.
;---------------------------------------------------------------\
; *
; MSMAllocateRCB zeroed out the RProtocolWorkspace field. *
; ESI = Logical address of ECB. *
; EDI = Physical address of ECB. (for BusMaster systems) *
; *
;---------------------------------------------------------------/
mov edx, dword ptr [esi].RProtocolWorkspace+0 ; Get first dword
mov dword ptr [ebp].HostPWSList1[eax*4], edx ; Save first dword
mov edx, dword ptr [esi].RProtocolWorkspace+4 ; Get 2nd dword
mov dword ptr [ebp].HostPWSList2[eax*4], edx ; Save 2nd dword
mov [ebp].HostRCBList[eax*4], esi ; Save log. address of ECB.
if BusMaster
mov [ebp].AdapterRCBList[eax*4], edi ; Save phys. adr of ECB.
else
add esi, LogicalToPhysical ; Convert RCB to physical.
mov [ebp].AdapterRCBList[eax*4], esi
endif
inc eax ; EAX = 1 (Index).
mov [ebp].ReceiveQueueTail, eax
WaitOnFirmware:
;---------------------------------------------------------------\
; *
; Wait for NIC to report its initial status. *
; *
;---------------------------------------------------------------/
mov ecx, CountForLoop ; ECX = Loop counter.
shl ecx, 1 ; Allow more time for shutdown.
mov edx, [ebp].IdleMailbox ; EDX -> NIC's Abend port 10h.
WaitForFirmwareStatusLoop:
in al, dx ; Read status.
or al, al ; Non Zero return?
jnz short FirmwareStatusComplete ; Jump if so.
dec ecx ; Loop again?
jnz WaitForFirmwareStatusLoop ; Jump if so.
;---------------------------------------------------------------\
; *
; The DriverShutdown routine may just need some more time *
; (especially on a faster machine). We will retry shutdown up *
; to three more times before concluding the adapter won't reset.*
; *
;---------------------------------------------------------------/
inc [ebp].InDriverReset ; Inc the inuse/counter.
cmp [ebp].InDriverReset, 4 ; Shutdown more than 3 times?
jbe DriverResetRetry ; Jump if no (try again).
lea eax, FirmwareInitErrorMsg ; EAX -> Error Message.
jmp DriverResetErrorExit ; Exit Driver Reset.
FirmwareErrorStatus:
test al, 40h ; Static RAM Error?
lea eax, StaticMemoryErrorMsg ; EAX -> RAM Error message.
jnz DriverResetErrorExit ; Jump if so.
lea eax, RomErrorMsg ; EAX -> ROM Error message.
jmp DriverResetErrorExit ; Exit Driver Reset.
FirmwareStatusComplete:
test al, 80h ; Firmware Init successful?
jz FirmwareErrorStatus ; Jump if not.
;---------------------------------------------------------------\
; *
; Tell NIC where to read firmware from. *
; *
;---------------------------------------------------------------/
inc edx ; DX -> Mailbox+1.
mov eax, DriverFirmwareSize ; EAX = Size of firmware.
out dx, al ; Send LSB of size.
inc edx ; DX -> Mailbox+2.
mov al, ah
out dx, al ; Send MSB of size.
mov eax, DriverFirmwareBuffer ; EAX -> Firmware Buffer
if BusMaster
call MSMGetPhysical ; Convert to Physical Addr.
else
add eax, LogicalToPhysical ; Convert to Physical Addr.
endif
add edx, 2 ; DX -> Mailbox+4.
out dx, eax ; Send Buffer address.
add edx, 4 ; DX -> Mailbox+8.
xor eax, eax ; Dest. = 0.
out dx, eax ; Send Destination addr.
mov edx, [ebp].IdleMailbox ; DX -> Mailbox + 0.
out dx, al ; Send command.
mov edx, [ebp].ParametersMailbox ; DX -> Parm Port.
mov ecx, CountForLoop ; ECX = Loop counter.
shl ecx, 1 ;TNL 3/30/95 We need to wait
; a little longer here.
WaitForDownloadLoop:
in eax, dx ; EAX = Download status.
cmp eax, 11111111h ; Code Running?
jz short FirmwareOperational ; Jump if yes.
dec ecx ; Loop again?
jnz WaitForDownloadLoop ; Jump if so.
lea eax, FirmwareLoadErrorMsg ; EAX -> Error Message.
jmp DriverResetErrorExit ; Exit Driver Reset.
;---------------------------------------------------------------\
; *
; Now fill in adapter parameter block and then give the block's *
; address to the adapter, so the firmware can copy it down. *
; *
;---------------------------------------------------------------/
FirmwareOperational:
if BusMaster
lea eax, [ebx].MLIDNodeAddress ; Store node address.
call MSMGetPhysical
mov [ebp].NodeAddressPointer, eax
mov eax, [ebx].MLIDMaximumSize ; Store Max Packet
mov [ebp].MaxReceivePacketSize, eax ; size.
lea eax, [ebp].PacketTxTooBigCount ; Save ptr to Stat table.
call MSMGetPhysical
mov [ebp].GenericStatisticsPointer, eax
movzx eax, [ebp].CustomVariableCount ; Store number of
mov [ebp].CustomStatisticsCount, ax ; custom variables.
lea eax, [ebp].AdapterRCBList ; Save ptr to RCB list.
call MSMGetPhysical
mov [ebp].RCBListPointer, eax
IF DEBUG
mov eax, [ebp].BufferAddress ;# Set up diagnostic buffer
call MSMGetPhysical
mov [ebp].DiagnosticBufferPointer, eax
ENDIF
else
mov ecx, LogicalToPhysical ; Store conversion
mov [ebp].LogicalToPhysicalOffset, ecx ; parameter.
lea eax, [ebx].MLIDNodeAddress ; Store node address.
add eax, ecx
mov [ebp].NodeAddressPointer, eax
mov eax, [ebx].MLIDMaximumSize ; Store Max Packet
mov [ebp].MaxReceivePacketSize, eax ; size.
lea eax, [ebp].PacketTxTooBigCount ; Store pointer to
add eax, ecx ; statistics table.
mov [ebp].GenericStatisticsPointer, eax
movzx eax, [ebp].CustomVariableCount ; Store number of
mov [ebp].CustomStatisticsCount, ax ; custom variables.
lea eax, [ebp].AdapterRCBList ; Store pointer to
add eax, ecx ; RCB list.
mov [ebp].RCBListPointer, eax
IF DEBUG
mov eax, [ebp].BufferAddress ; Set up diagnostic buffer
add eax, ecx
mov [ebp].DiagnosticBufferPointer, eax
ENDIF
endif
;-----------------------------------------------------------------\
; *
; EtherTSMUpdateMulticast will either call DriverPromiscuousChange*
; if promisc. mode is enabled, or DriverMulticastChange. *
; Because both procedures normally write to the UpdateParmMailbox *
; I/O port, the flag InDriverReset is used to prevent this. *
; Otherwise the adapter firmware would become out of sync with us,*
; since it's waiting for a UpdateParmMailbox notification that the*
; address of the adapter parameter block is now available, *
; (see label WaitForParameterBlock in adapter.386 code). *
; *
;-----------------------------------------------------------------/
call EtherTSMUpdateMulticast ; Store Multicast
; variables.
SkipMulticastUpdate:
mov eax, dword ptr [ebx].MLIDNodeAddress+0 ; Copy Node Address
mov dword ptr [ebp].HostNodeAddress+0, eax ; to structure.
mov ax, word ptr [ebx].MLIDNodeAddress+4
mov word ptr [ebp].HostNodeAddress+4, ax
;--------------------------------------------------------------------------
;JCJ 11-July-1997 In an OP_SCOPE_ADAPTER reset we have to reactivate any previous
; partial shutdown boards. SPD #160930
;--------------------------------------------------------------------------
push ebx ;keep pointer to frame data space
xor ecx, ecx ;for(i=0; i<4; i++)
ReactivateBoard: ;i is the board index
mov ebx, [ebp].MSMVirtualBoardLink+(ecx*4)
or ebx, ebx ;Valid frame data space
jz CheckNextBoard ;no, take next board
movzx eax, [ebx].MLIDBoardNumber ;Board Number in eax
call SetDriverDataBoardNumber ;Set the board number in
;adapter dataspace
CheckNextBoard:
inc ecx ;next board
cmp ecx, 4 ;have checked all 4 boards?
jb ReactivateBoard ;no, go for next board
pop ebx
;JCJ END SPD #160930
lea eax, [ebp].LogicalToPhysicalOffset ; EAX -> Parm block.
if BusMaster
call MSMGetPhysical
else
add eax, LogicalToPhysical ; Convert to phys.
endif
mov edx, [ebp].ParametersMailbox ; EDX -> parm port.
out dx, eax ; Send address to adapter.
mov edx, [ebp].UpdateParmMailbox ; EDX -> Parm update port.
mov al, 1 ; Set it.
out dx, al
mov ecx, CountForLoop ; Set loop counter.
shl ecx, 1
;---------------------------------------------------------------\
; *
; Note: A zeroed out UpdateParmMailbox means the adapter has *
; gotten our command but is probably still processing it. *
; *
;---------------------------------------------------------------/
WaitForParametersLoop:
in al, dx ; AL = Parm update value.
or al, al ; Cleared?
jz short ParametersUploaded ; Jump if so.
dec ecx
jnz WaitForParametersLoop
lea eax, ParameterPassErrorMsg ; EAX -> Error message.
jmp short DriverResetErrorExit ; Exit DriverReset.
ParametersUploaded:
if AddPolling
mov edx, [ebp].PollingMailbox ;# Clear Polling Mailbox.
xor al, al ;#
out dx, al ;#
endif
mov edx, [ebp].EisaSystemDoorbellEnable ; Port 0Eh.
inc edx ; DX = Doorbell + 1.
mov al, -1 ; Reset the status port,
out dx, al ; (EISA_DOORBELL_STATUS).
dec edx ; DX = Doorbell + 0.
mov eax, 1 ; Enable it,
out dx, al ; (EISA_DOORBELL_ENABLE).
sub edx, 6 ; DX = Global Config port.
mov al, [ebp].GlobalConfigValue
out dx, al
inc edx ; DX = System interrupt port.
mov al, 1
out dx, al ; Enable it.
DontEnableInterrupts:
;TNL 7/27 Add next line
mov [ebp].InDriverReset, 0 ; Clear InDriverReset flag.
xor eax, eax
ret ; Init successful.
DriverResetErrorExit:
;TNL 7/27 Add next line
mov [ebp].InDriverReset, 0 ; Clear InDriverReset flag.
or eax, eax ; Clear the zero flag.
ret
DriverReset endp
;-----------------------------------------------------------------------
;JCJ 11-July-1997 This routine is added to set the adapter data space BoardNumber
; Variable. The same has to be done from DriverReset
; twice and from DriverShutdown once. SPD #160930
;------------------------------------------------------------------------
subttl -- SetDriverDataBoardNumber --
;***********************************************************************
; Name: SetDriverDataBoardNumber
;
; Description: This is a local procedure which will be called from DriverReset
; and DriverShutdown. This procedure sets the adapterdata
; board field.
;
; On Entry: EAX Will have board number or -1(In case of shutdown)
; EBX @ Frame Data Space
; ECX N/A
; EDX N/A
; EBP @ Adapter Dataspace
; ESI N/A
; EDI N/A
;
; On return: EDX Destroyed
;
;************************************************************************
align 16
SetDriverDataBoardNumber proc
movzx edx, [ebx].MLIDFrameID ;edx = MLIDFrameID
cmp dx, 2 ;Config table is for EII?
jne check802_2 ;No check for 802.2
mov [ebp].BoardNumberEII, ax ;Yes, Keep boardnumber
ret
check802_2:
cmp dx, 3 ;Is it for 802.2?
jne check802_3 ;No, Check 802.3
mov [ebp].BoardNumber8022, ax ;Yes, Keep boardNumber
ret
check802_3:
cmp dx, 5 ;Is it for 802.3?
jne check_SNAP ;No, Check SNAP
mov [ebp].BoardNumber8023, ax ;Yes, Keep boardNumber
ret
check_SNAP:
cmp dx, 10 ;Is it for SNAP?
jne SetDriverDataBoardNumberExit
mov [ebp].BoardNumberSNAP, ax
SetDriverDataBoardNumberExit:
ret
SetDriverDataBoardNumber endp
subttl -- UpdateDriverData --
;***********************************************************************
; Name: UpdateDriverData
;
; Description: This is a local procedure which will be called from DriverReset
; and DriverShutdown. This is called after setting the driver
; parameters. This procedure updates adapter with the board field.
;
; On Entry: EBP @ Adapter Dataspace
;
; On return: EAX Destroyed
; ECX Destroyed
; EDX Destroyed
;
; Flags: Z Reset incase of error
;
;************************************************************************
align 16
UpdateDriverData proc
mov edx, [ebp].UpdateParmMailbox ; DX -> Parm Port.
mov ecx, CountForLoop ; Set loop counter.
WaitForLoop:
in al, dx
or al, al ;Cleared?
jz SetMailBox
loop WaitForLoop ;else wait till counter elapse.
SetMailBox: ;Here I'm not looking for the timeout
mov al, 1 ;Now set the mail box to tell him
out dx, al ;that driver parameter need to be updated.
mov ecx, CountForLoop ;Wait for the adapter response
shl ecx, 1
WaitForAdapterResponse:
in al, dx ;al=param update value
or al, al ;Cleared
jz short ExitUpdateDriverData ;Yes We're done
loop WaitForAdapterResponse ;No, loop there.
lea eax, ParameterPassErrorMsg ;Counter reaches 0, ErrorExit
or eax, eax ;Reset zero flag.
ExitUpdateDriverData:
ret
UpdateDriverData endp
;JCJ END SPD #160930
subttl -- DriverShutdown --
page
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverShutdown, NE3200/API/SHUTDOWN )
;
; Name: DriverShutdown
;
; Description: This routine will set the card into an idle/reset state
; and return any ECB's that it is holding.
;
; On Entry: EAX set to OP_SCOPE_ADAPTER if the adapter specified by EBP
; is to be shutdown. Otherwise set to OP_SCOPE_LOGICAL_BOARD
; which indicates that only the logical board specified
; by EBX is to be shutdown.
; EBX @ Frame Data Space
; ECX 0 if Permanent Shutdown
; EDX N/A
; EBP @ Adapter Data Space
; ESI N/A
; EDI N/A
;
; Note: Interrupts are disabled.
;
; On Return: EAX 0 if successful
; EBX Preserved
; ECX Destroyed
; EDX Destroyed
; EBP Preserved
; ESI Destroyed
; EDI Destroyed
;
; Flags:
;
; Note: Interrupts preserved.
;
; Remarks: This routine is called by the MSM media module and by
; DriverReset. It is called at process time.
;
; See Also: ETHERTSM\EtherTSMShutdown
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
align 16
public DriverShutdown
DriverShutdown proc
cmp eax, OP_SCOPE_ADAPTER
je ShutdownDriver
;------------------------------------------------------------------------
;JCJ 11-July-1997 Now the scope is OP_SCOPE_LOGICAL_BOARD. This means
; a logical board needs to be shutdown. spd #160930
;------------------------------------------------------------------------
test [ebx].MLIDSharingFlags, IODetachedBit ;Shutdown bit is set
jz SkipShutDownBoard ;No, Do not reset board
;Since DriverShutdown will not be called from DriverReset with OP_SCOPE_LOGICAL_BOARD
;InDriverReset need not be checked.
mov eax, -1
call SetDriverDataBoardNumber ;Reset Set the board number in
;adapter space
;------------------------------------------------------------------------
;Now inform the firmware that driver parameters have been updated.
SkipShutDownBoard:
Call UpdateDriverData
jnz ShutDownExit ;On successfull return Z flag
xor eax, eax ;will be set.
ShutDownExit:
ret
;JCJ 11-July-1997 spd #160930
;---------------------------------------------------------------\
; *
; Set card into idle state and then reset it. *
; *
;---------------------------------------------------------------/
ShutdownDriver:
mov [ebp].DriverShutdownType, ecx ; Save for later checking.
;;TNL cmp [ebp].InDriverInit, 0 ; Called by Driver Init?
cmp [ebp].InDriverReset, 0 ; Called by Driver Reset?
jnz short ShutdownResetNIC ; Jump if so.
mov edx, [ebp].IdleMailbox ; EDX -> Idle adapter port.
mov al, 1 ; Set it.
out dx, al
mov ecx, CountForLoop ; ECX = loop counter.
ShutdownWaitForIdle:
in al, dx ; Read idle adapter port.
or al, al ; Cleared by adapter.
jz short ShutdownStopInterrupts ; Jump if so.
dec ecx
jnz ShutdownWaitForIdle
ShutdownStopInterrupts:
cmp [ebp].DriverShutdownType, 0 ; Is this a permanent Shutdown?
jne ShutdownResetNIC ; Jmp if No (Go reset the card).
mov edx, [ebp].EisaSystemDoorbellEnable ; Get I/O reg for Disable
; interrupts.
xor al, al ;
out dx, al ; Disable interrupts.
jmp short ShutdownClearInterrupt ; Continue.
ShutdownResetNIC:
mov edx, [ebp].ResetRegister ; EDX -> NIC Reset Port.
mov eax, 1 ; Set Reset Bit.
out dx, eax ; Reset the NIC.
mov edx, [ebp].IdleMailbox ; Clear Abend mailboxes.
xor eax, eax
out dx, al
mov ecx, CountForReset ; Allow reset settling time.
ShutdownHoldReset:
loop ShutdownHoldReset ; Give NIC time to go Idle.
mov edx, [ebp].ResetRegister ; EDX -> NIC Reset Port.
out dx, eax ; Clear NIC's reset state.
;---------------------------------------------------------------\
; *
; Clear Interrupt Status in case it's level triggered. *
; *
;---------------------------------------------------------------/
ShutdownClearInterrupt:
mov eax, 1 ; Select sticky bit to clear.
mov edx, [ebp].EisaSystemDoorbellStatus
in al, dx
out dx, al ; Reset bits.
;---------------------------------------------------------------\
; *
; Return any Receive ECB's. *
; *
;---------------------------------------------------------------/
mov ecx, TOTAL_RCBS
sub ecx, [ebp].NeedRCBCount ; ECX = RCBs in use.
or ecx, ecx ; Any RCBs in use?
jz short ShutdownReturnTCB ; Jump if not.
ShutdownReturnRCBLoop:
mov eax, [ebp].ReceiveQueueHead ; EAX = Head of list Index.
mov esi, [ebp].HostRCBList[eax*4] ; ESI -> RCB.
inc eax ; Bump index.
and eax, TABLE_MASK
mov [ebp].ReceiveQueueHead, eax ; Save new head.
cmp esi, -1 ; Is the pointer valid?
je ShutdownNextRCB ; Jump if NO.
MSMReturnRCB ; Return RCB.
ShutdownNextRCB:
dec ecx ; Get next one.
jnz short ShutdownReturnRCBLoop
ShutdownReturnTCB:
if TxQueue
cmp [ebp].MSMTxFreeCount, TOTAL_TCBS ; TCBs given back?
je ShutdownInitVariables ; Jump if so.
mov eax, [ebp].TCBQueueHead ; EAX = Index for Head of TCB list.
mov esi, [ebp].HostTCBList[eax*4] ; ESI = RCB.
inc al
mov [ebp].TCBQueueHead, eax ; Save new index.
inc [ebp].MSMTxFreeCount
if UseFastCalls
push ebp
push ebx
call EtherTSMFastSendComplete ; Return the TCB.
pop ebx
pop ebp
else
call EtherTSMSendComplete
endif
jmp ShutdownReturnTCB
else
mov esi, [ebp].TCBInProcess ; ESI -> possible TCB.
or esi, esi ; Valid TCB?
jz short ShutdownInitVariables ; Jump if not.
mov [ebp].TCBInProcess, 0 ; Clear pointer.
if UseFastCalls
push ebp
push ebx
call EtherTSMFastSendComplete ; Return TCB.
pop ebx
pop ebp
else
call EtherTSMSendComplete ; Return TCB.
endif
endif
ShutdownInitVariables:
if TxQueue
mov [ebp].MSMTxFreeCount, TOTAL_TCBS ; TOTAL_TCBS = 128;
mov [ebp].TCBQueueHead, 0
mov [ebp].TCBQueueTail, 0
else
mov [ebp].MSMTxFreeCount, 1 ; Allow 1 transmit at a time.
endif
mov [ebp].NeedRCBCount, TOTAL_RCBS ; Reset Need RCB count to MAX.
cmp [ebp].DriverShutdownType, 0 ; Is this a permanent Shutdown?
jne ShutdownSetupLists ; Jump if No.
;---------------------------------------------------------------\
; *
; We're in the process of totally shutting down the driver due *
; to a call to our DriverRemove. We reset NeedRCBCount to zero *
; so that any pending interrupts that invoke our DriverISR will *
; not cause this HSM to request more RCBs be allocated due to *
; the NeedRCBCount being non-zero. *
; *
;---------------------------------------------------------------/
mov [ebp].NeedRCBCount, 0 ; Reset Need RCB count to Zero.
;---------------------------------------------------------------\
; *
; Reinitialize the Host and RCB Lists, *
; (each entry serves as a pointer to a Receive ECB). *
; *
;---------------------------------------------------------------/
ShutdownSetupLists:
lea edi, [ebp].AdapterRCBList ; Setup to initialize RCB List.
mov eax, -1
mov ecx, TABLE_SIZE + TCB_TABLE_SIZE
cld
rep stosd ; Reset all entries to -1.
lea edi, [ebp].HostRCBList ;TNL 7/27/95 Added this line.
xor eax, eax
mov ecx, TABLE_SIZE + TCB_TABLE_SIZE
rep stosd ; Clear all entries to 0.
xor eax, eax ; Successful return.
ret
DriverShutdown endp
;***********************************************************************\
; BEGIN_MANUAL_ENTRY( PollTimeoutRoutine)
;
; Name: PollTimeoutRoutine
;
; Description: This routine saves the timeout value.
;
; On Entry: EAX Timeout Value
; EBX N/A
; ECX N/A
; EDX N/A
; EBP N/A
; ESI N/A
; EDI N/A
;
; Note: Interrupts are in any state.
;
; On Return: EAX Preserved
; EBX Preserved
; ECX Preserved
; EDX Preserved
; EBP Preserved
; ESI Preserved
; EDI Preserved
;
; Flags:
;
; Note: Interrupts preserved.
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
PollTimeoutRoutine proc
mov PollingTimeoutValue, eax ; Save timeout value.
ret ; Exit.
PollTimeoutRoutine endp
subttl -- DriverRemove --
page
;***********************************************************************\
;
; BEGIN_MANUAL_ENTRY( DriverRemove, NE3200/API/REMOVE )
;
; Name: DriverRemove
;
; Description: This routine calls the MSM to return our resources.
;
; On Entry: EAX N/A
; EBX N/A
; ECX N/A
; EDX N/A
; EBP N/A
; ESI N/A
; EDI N/A
;
; Note: Interrupts are in any state.
;
; On Return: EAX Destroyed
; EBX Preserved
; ECX Destroyed
; EDX Destroyed
; EBP Preserved
; ESI Preserved
; EDI Preserved
;
; Flags:
;
; Note: Interrupts preserved.
;
; Remarks: This routine is called by the OS at unload.
; It is called at process time.
;
; See Also: MSM\MSMDriverRemove
;
; END_MANUAL_ENTRY
;
;***********************************************************************/
;
align 16
public DriverRemove
DriverRemove proc
CPush
mov eax, DriverModuleHandle
call MSMDriverRemove
CPop
ret ; Exit.
DriverRemove endp
OSCODE ends
end