Microsoft/3Com LAN Manager Network Driver Interface Specification Version 2.0.1 Published 05 Oct., 1990 Copyright 1988, 1989, 1990 3Com Corporation/Microsoft Corporation NOTICE This specification is intended for use by those developing or using networking products. This specification may be copied freely for that purpose as long as copyright notice is preserved on all copies of the specification. No fee or royalty is required by either 3Com Corporation or Microsoft Corporation to develop products which use the information contained within this specification. Information contained in this specification may be included in documents, presentations, or products of third parties; however, authorship must be attributed jointly to 3Com Corporation and Microsoft Corporation, and appropriate copyright notices must be placed in any such documents or presentations. Additional copies of this specification may be obtained from 3Com Corporation or Microsoft Corporation. Table of Contents Chapter 1 - Introduction Definition of Terms 1-1 Scope of this Document 1-2 Changes for this Version 1-2 Chapter 2 - Configuration and Binding Configuration and Binding Process 2-1 Chapter 3 - Protocol to MAC Interface Description Transmission 3-1 Reception 3-1 Non Host-Buffered Adapter 3-2 Host-Buffered Adapter 3-3 Indication Control 3-3 Status Indication 3-3 General Requests 3-4 System Requests 3-5 Protocol Manager Primitives 3-5 Chapter 4 - Data Structures Module Characteristics 4-1 Common Characteristics 4-1 MAC Service-Specific Characteristics 4-4 MAC Service-Specific Status Table 4-8 MAC Upper Dispatch Table 4-9 Protocol Service-Specific Charateristics Table 4-10 Protocol Lower Dispatch Table 4-10 Characteristics Table for NetBIOS Drivers 4-11 Frame Data Description 4-13 Transmit Buffer Descriptor 4-13 Transfer Data Buffer Descriptor 4-14 Receive Chain Buffer Descriptor 4-14 PROTOCOL.INI 4-15 Configuration Memory Image 4-17 ConfigMemoryImage 4-17 ModuleConfig 4-17 KeywordEntro 4-18 Param 4-19 Bindings List 4-20 Chapter 5 - Specification of Primitives Direct Primitives 5-3 TransmitChain 5-3 TransmitConfirm 5-4 ReceiveLookahead 5-5 TransferData 5-6 IndicationComplete 5-7 ReceiveChain 5-8 ReceiveRelease 5-9 IndicationOff 5-9 IndicationOn 5-10 General Requests 5-11 Initiate Diagnostics 5-11 ReadErrorLog 5-12 SetStationAddress 5-12 OpenAdapter 5-13 CloseAdapter 5-14 ResetMAC 5-14 SetPacketFilter 5-15 AddMulticastAddress 5-16 DeleteMulticastAddress 5-17 UpdateStatistics 5-17 ClearStatistics 5-18 Interrupt 5-18 SetFunctionalAddress 5-19 SetLookahead 5-19 General Request Confirmation 5-21 StatusIndication 5-22 RingStatus 5-22 AdapterCheck 5-23 StartReset 5-24 EndReset 5-25 Interrupt 5-25 System Requests 5-26 InitiateBind 5-26 Bind 5-27 InitiatePrebind (OS/2 only) 5-27 InitiateUnbind 5-28 Unbind 5-29 Protocol Manager Primitives 5-30 GetProtocolManagerInfo 5-30 RegisterModule 5-31 BindAndStart 5-33 GetProtocolManagerLinkage 5-34 GetProtocolIniPath 5-35 RegisterProtocolManagerInfo 5-35 InitAndRegister 5-36 UnbindAndStop 5-37 BindStatus 5-38 RegisterStatus 5-41 Chapter 6 - Protocol Manager Protocol Manager Initialization 6-1 Static Binding Sequence 6-1 OS/2 CallingConvention 6-3 DOS Calling Convention 6-4 Chapter 7 - VECTOR and Dynamic Binding Static VECTOR Binding 7-1 Dynamic VECTOR Binding 7-2 Dynamic Binding/Unbinding in the DOS Environment 7-2 Dynamic Binding/Unbinding in the OS/2 Environment 7-3 VECTOR Demultiplexing 7-4 Appendix A: System Return Codes A-1 Appendix B: Reference Material B-1 Appendix C: 802.3 Media Specific Statistics C-1 Appendix D: 802.5 Media Specific Statistics D-1 Appendix E: Utilities Provided with the Protocol Manager E-1 Chapter 1: Introduction This document describes the LAN Manager network driver architecture and interfaces that let a DOS or OS/2 system support one or more network adapters and protocol stacks. This architecture provides a standardized way for writing drivers for network adapters and communications protocols. It also solves the problem of how to configure and bind multiple drivers into the desired set of layered protocol stacks. Drivers written to the interfaces defined here will function concurrently in a system with other networking and protocol drivers, and will operate correctly with the LAN Manager software for DOS and OS/2. Definition of Terms To simplify the job of supporting multiple adapters and protocols, the architecture defines four kinds of drivers. - Media Access Control (MAC) drivers, which provide low-level access to network adapters. The main function of a MAC driver is to support transmitting and receiving packets, plus some basic adapter management functions. MAC drivers are device drivers that are loaded during system initialization and remain permanently in memory. Since they cannot be unloaded, they are called "static". - Protocol drivers, which provide higher-level communication services from data link to application (depending on the driver). An example is a NetBIOS driver that provides a NetBIOS interface at the top and talks to a MAC driver at the bottom. Protocol drivers can be device drivers, TSRs, or transient DOS applications. A protocol driver is called "static" if it cannot be unloaded. A protocol driver is called "dynamic" if it can be loaded and unloaded on demand. - MAC-layer entities, which bind to real MAC drivers and expose a new MAC-like layer interface on top. Possible examples are MAC bridges, test tools, or interface mappings which change the NDIS interface to meet some environment-specific administrative requirement. - The Protocol Manager driver. This is a special driver that provides a standardized way for multiple MAC and protocol drivers to get configuration information and bind together into the desired protocol hierarchy. The Protocol Manager gets all configuration information from a central file, PROTOCOL.INI. Scope of this Document This document defines: 1. Protocol Manager functions and interfaces for configuration and binding of MAC and protocol drivers. 2. The software interface between MAC and protocol drivers. Separate documents will specify the configuration and interface details for other kinds of protocol drivers, including data link and transport drivers. Changes for this Version The major highlights of this version compared to the last (1.0) are: 1. Support for dynamic binding/unbinding of protocol modules, allowing protocols to be swapped in and out of memory as needed. No changes are required of MAC drivers to support the dynamic bind/unbind features. In particular NDIS 1.0.1 conformant MACs will support dynamically binding protocol modules. 2. Additional Protocol Manager functions to support dynamic binding and future administrative requirements. 3. Some adjustments to the Reset MAC function, StartReset, and EndReset primitives were made to correct some inconsistencies and keep logic out of the criticial paths. 4. Additional fields were added to certain tables to provide additional information. The presence or absence of these fields can be determined by examining the length field in each table. 5. Some new recommendations and clarifications on such issues as double-word alignment of data blocks, the use of the permanent station address, the copying of DS and entry points, the use of 80386 32-bit registers, the release of internal re- sources before confirmations, the handling of 0 length data blocks, the formatting of MAC headers, the use of zero handles, new transmit error codes for Token Ring to support source- routing, and various other points that needed additional clarifications. 6. A standard for protocol service-specific characteristics tables. 7. The inclusion of additional 802.3 and 802.5 specific information and added statistics definitions. 8. Additional information and caveats to help developers. 9. The Protocol Manager now has a transient component (in some configurations)called PROTMAN.EXE. This is now described with certain restricitions imposed on Protocol Manager primitives. 10. Some new error response codes were defined. 11. A new appendix, Appendix E, was added to describe some helpful bind and configuration management utilities provided with Protocol Manager. 12. Selected statistics designated as manditory for both service-specific and media specific statistics(802.3 and 802.5). 13. Extended 802.3 statistics to include Number_of_Underruns. 14. OpenAdapter function expanded to permit driver return of vendor specified warning errors and/or hardware error codes. It is not expected that any of these changes will result in incompatibilities with protocol and MAC drivers written to previous versions of this specification. Great care was taken to avoid creating incompatibilities. It is the protocol's responsibility to identify and interoperate with older NDIS version driver imple- mentations that may not have implemented support for statistics. Older network drivers will co-exist with network drivers written to this specification. However, to take advantage of new features (such as dynamic binding), developers may wish to update their protocol drivers tobe NDIS 2.0.1 compliant. Chapter 2: Configuration and Binding A network server or workstation includes at least one Media Access Control (MAC) and one protocol driver, plus the Protocol Manager driver. More complex configurations may have multiple MAC and protocol drivers. The Protocol Manager is always defined in CONFIG.SYS to load before any MAC or protocol drivers. Its job is to read the configuration information out of the PROTOCOL.INI file and make this available to MAC and protocol drivers which load later. MAC and protocol drivers use this information to set initialization parameters and allocate memory appropriately. For example, a NetBIOS driver may use the configuration information provided by the Protocol Manager to determine its maximum number of names and sessions. As each driver configures and initializes itself, it identifies itself to the Protocol Manager using a driver-defined "module name" and "characteristics table". The module name defines a kind of logical name for the communication service provided by the driver. The characteristics table provides specific parameters about the service and the set of entry points the driver uses to communicate with other drivers. A single driver may identify itself to the Protocol Manager as multiple logical modules if, for example, it implements more than one layer of protocol interface (such as transport and data link). Before two modules can communicate, they must be bound together. Binding is the process of two modules exchanging characteristics tables so that they can access each other's entry points. This establishes the linkage they need to make requests of one another and indicate asynchronous request completion. Binding is controlled by the Protocol Manager based on information from PROTOCOL.INI. Binding can be either static or dynamic for protocol drivers. If a protocol driver is static, then its binding is static. If it is dynamic, then its binding is dynamic. A dynamic protocol driver can be unbound from its bound drivers prior to unloading itself from memory. This unbinding process is also controlled through the Protocol Manager. Configuration and Binding Process In the typical case of a system with one MAC driver and a NetBIOS driver, the set of drivers load and initialize as follows: 1. Protocol Manager loads, initializes, and reads PROTOCOL.INI. 2. MAC driver loads. It calls GetProtocolManagerInfo to get any needed configuration information, like its DMA channel. 3. MAC driver initializes and calls RegisterModule to identify itself as the module named e.g. "ETHERCARD." This call passes ETHERCARD's characteristics table to Protocol Manager. 4. NetBIOS driver loads. It calls GetProtocolManagerInfo to get any needed configuration information, like the maximum number of names, sessions, and commands to support. 5. NetBIOS driver initializes and calls RegisterModule to identify itself as the module named "NetBIOS". This call passes NetBIOS's characteristics table to Protocol Manager and indicates that NetBIOS wants to bind to ETHERCARD. 6. After all device drivers have loaded, Protocol Manager determines from the information supplied on previous RegisterModule requests that NetBIOS must bind to ETHERCARD. Using a defined dispatch address in the characteristics table for NetBIOS, Protocol Manager calls NetBIOS and instructs it to bind to ETHERCARD. The call, InitiateBind, includes the characteristics table for ETHERCARD. 7. NetBIOS calls ETHERCARD, requesting to Bind. The modules exchange characteristics tables with each other. They now have each other's entry points and are bound. 8. NetBIOS may now call ETHERCARD at its defined entry points for transmitting and receiving packets (see next section). If the example NetBIOS driver was dynamically loadable, the binding to the ETHERCARD MAC would be done through the Protocol Manager's VECTOR facility (see Chapter 7). The Vector shields the static MAC driver from the details of dynamic binding. Chapter 3: Protocol to MAC Interface Description The interface between a protocol and MAC driver provides for the transmission and reception of network packets, called frames. The interface includes other functions for controlling and determining the status of the network adapter controlled by the MAC. To allow for efficient use of memory and to minimize buffer copies, frames being transmitted and received are passed between protocol and MAC using a scatter/gather buffer description convention. This passes an array of pointers/lengths called a frame buffer descriptor. There are three types of these descriptors, one for describing frames being transmitted (TxBufDescr) and two for frames being received (RxBufDescr and TDBufDescr). Overall, the calls at the protocol/mac interface are grouped into categories of transmission, reception, indication control, status indications, and general requests. An additional category of function, system requests, is generic to all drivers. Transmission Transmitting data can work either synchronously or asynchronously, at the option of the MAC. Protocols must be able to handle both cases. Primitives are TransmitChain and TransmitConfirm. Protocol MAC Transmit Chain -CALL-> Call passes TxBufDescr and unique handle. MAC may copy data now or later. <-RETURN- Return indicates if data has been copied. If not, MAC now owns frame data blocks and will copy them asynchronously. Later on, after data is copied by MAC: TransmitConfirm <-CALL- Call supplies unique handle from Transmit. -RETURN-> Data block ownership returned to protocol. NOTE: If the MAC transmits the frame synchronously, it indicates this on the return from TransmitChain and will not generate a TransmitConfirm. Reception Receiving data can work in either of two ways, depending on the MAC. Protocols must be able to handle both cases. - The MAC generates a ReceiveLookahead indication that points to part or all of the received frame in contiguous storage. This is called the "lookahead" data. The protocol may issue a TransferData call back to the MAC if it wants the MAC to copy all or part of the received frame to protocol storage. The protocol may, of course, copy the look ahead data itself. In some imple- mentations, this may be the entire frame. - The MAC generates a ReceiveChain indication that points to a RxBufDescr that describes the entire frame received. The protocol may copy the data immediately or later. If later, it releases the frame buffer areas back to the MAC via a call to ReceiveRelease. Generally, the first approach will be implemented by MAC drivers for non-host buffered network adapters, while drivers for host buffered network adapters will implement the second. Non-host buffered adapters that use programmed I/O or DMA will generally provide a small leading portion of the received frame as look ahead data, whereas those using a single memory mapped buffer will usually provide the whole frame. In either case, the protocol must validate the received packet very rapidly (within a few instructions) and to reject it if necessary. This is very important to performance in a multi- protocol environment. The following sections illustrate the non host-buffered adapter versus host-buffered adapter receive scenarios: Non Host-Buffered Adapter MAC Protocol ReceiveLookahead -CALL-> Call passes pointer to lookahead data. Protocol examines this data. If protocol wants the frame and look ahead wasn't the whole frame, the protocol can ask MAC to transfer the frame: TransferData <-CALL- Passes TDBufDescr indicating where to put the received data. -RETURN-> <-RETURN- Upon return from protocol, MAC re-enables the hardware. IndicationComplete -CALL-> MAC calls protocol to allow interuppt-time post processing. <-RETURN- Host-Buffered Adapter MAC Protocol ReceiveChain -CALL-> Call passes pointer to RxDataDescr. <-RETURN- Return tells if protocol accepts the frame, and if so, whether it copied the data. If accepted but not copied, ownership of data blocks passes to the protocol which copies the data asynchronously. IndicationComplete -CALL-> MAC calls protocol to allow interrupt-time post processing. <-RETURN- Later, if protocol deferred copying the data (this may occur during IndicationComplete) <-CALL- ReceiveRelease. The call supplies the unique handle from ReceiveChain. -RETURN-> Data block ownership returned to MAC. Indication Control Two primitives let a protocol selectively control when it can be called with indications from the MAC. These are IndicationOn and IndicationOff. Before calling an indication routine, the MAC implicitly disables indications. This means, for example, that if another frame arrives while the protocol is processing the indication for the previous one, the protocol will not be reentered. Likewise, if the protocol issues a TransmitChain for loopback data from within the ReceiveLookahead indication routine, it will not be reentered to process the loopback data reception. Protocols can re-enable indications upon returning from ReceiveLookahead, ReceiveChain or Status indications or by calling IndicationOn within the IndicationComplete routine. Status Indication Status indications are calls from a MAC to protocol that convey a change in adapter or network status. A status indication works much like a reception indication. The status indication handler is entered with indications disabled and there is a mechanism which will leave indications disabled. MAC Protocol Status -CALL-> Call passes status type and information. <-RETURN- IndicationComplete -CALL-> MAC calls protocol to allow interrupt-time post processing. <-RETURN- General Requests General requests are calls from a protocol to a MAC, asking it to do a general function such as open or close the network adapter or change the station address. General requests work much like a TransmitChain request, except the primitives are Request and RequestConfirm. Protocol MAC Request -CALL-> Issue request to MAC with unique handle. <-RETURN- Return indicates if request completed. Later, if request completed asynchronously: <-CALL- RequestConfirm. The call supplies unique handle from Request. -RETURN-> If the MAC satisfies the request synchronously, it indicates this on the return from Request and will not generate a RequestConfirm. System Requests System requests support module binding and management functions. They are usually made by the Protocol Manager to a MAC or protocol module, but can also be made by a protocol to another protocol or MAC module. System requests work much like general requests except that all are synchronous and the requests are not module specific. Upper Module Lower Module System -CALL-> Issue request to lower module. <-RETURN- Return indicates request completed. Protocol Manager Primitives Protocol Manager primitives are requests from protocol or MAC modules to the Protocol Manager for various Protocol Manager services. These requests are always synchronous. Protocol or MAC Protocol Manager Module Primitive -CALL-> Issue request to Protocol Manager <-RETURN- Return indicates request completed Chapter 4: Data Structures Module Characteristics Protocol and Media Access Control (MAC) modules are described by a data structure called a characteristics table. Each characteristics table consists of several sections: a master section called the common characteristics table and four subtables. The common characteristics table contains module- independent information, including a dispatch address for issuing system commands like InitiateBind to the module. The four module-specific subtables are chained off the common characteristics table. These define module-specific parameters and the entry points used for inter-module communication (such as the MAC/protocol interface functions). When two modules bind together, they exchange pointers to their common characteristics tables, so that each gets access to the other's descriptive information and entry points. NOTE: NDIS drivers must copy the Module DS and entry point addresses (from the Common Characteristics and Upper/Lower Dispatch Tables) to their local data segment at Bind time. In future versions of this specification, this information may be volatile. Having this information directly accessible will also improve performance. This information must not be copied prior to the Bind call and must not be used unless the Bind completes successfully. NOTE: The information in the characteristics table for a module is primarily informational, in support of network management and configuration tools. Upper modules binding to lower ones will NOT need to parse this information to adapt their behavior at the interface. They will generally just use the information to validate that they have been bound to the correct type of module. Most of the other information is provided in the structure to support information utilities. Some new fields have been added to some of the characteristics tables for V2.0.1. The size/length fields at the start of the tables can be checked to see if the new fields are available in the table. Common Characteristics The format of this information is identical for all modules. Note that all information in this section of the table is static. WORD Size of common characteristics table (bytes) BYTE Major NDIS Version (2 BCD digits - 02 for this version) BYTE Minor NDIS Version (2 BCD digits - 00 for this version) WORD Reserved BYTE Major Module Version (2 BCD digits) BYTE Minor Module Version (2 BCD digits) DWORD Module function flags, a bit mask : 0 - Binding at upper boundary supported 1 - Binding at lower boundary supported 2 - Dynamically bound (i.e., this module can be swapped out) 3-31 - Reserved, must be zero BYTE[16] Module name - ASCIIZ format BYTE Protocol level at upper boundary of module: 1 - MAC 2 - Data link 3 - Network 4 - Transport 5 - Session -1 - Not specified BYTE Type of interface at upper boundary of module: For MAC's: 1 => MAC For Data Links: To be defined For Transports: To be defined For Session: 1 => NCB For any level: 0 => private (ISV defined) BYTE Protocol level at lower boundary of module 0 - Physical 1 - MAC 2 - Data link 3 - Network 4 - Transport 5 - Session -1 - Not specified BYTE Type of interface at lower boundary of module: For MAC: 1 => MAC For Data Link: To be defined For Transport: To be defined For Session: 1 => NCB For any level: 0 => private (ISV defined) WORD Module ID filled in by Protocol Manager on return from RegisterModule WORD Module DS LPFUN System request dispatch entry point LPBUF Pointer to service-specific characteristics (NULL if none) LPBUF Pointer to service-specific status (NULL if none) LPBUF Pointer to upper dispatch table (see below; NULL if none) LPBUF Pointer to lower dispatch table (see below; NULL if none) LPBUF Reserved for future expansion, must be NULL LPBUF Reserved for future expansion, must be NULL NOTE: LPSZ Long pointer to an ASCIIZ string LPBUF Long pointer to a data buffer LPFUN Long pointer to a function In V1.0.1, the 2 bytes after the first WORD were required to be set to 0. For compatibility with V1.0.1, an NDIS spec major version number of 00 is interpreted the same as major version number 01. The module function flags bit mask must accurately specify the capabilities of the module. The Protocol Manager uses these fields; e.g. the "Dynamically bound" (bit 2) flag when set indicates that this module is a dynamically loadable and unloadable module. Such a module can only be used in the Protocol Manager dynamic mode. The upper and lower boundary protocol level and interface type bytes must accurately specify the protocol level and interface type. The Protocol Manager uses these fields. If an interface does not support NDIS bindings or a protocol level is undefined at the interface, a value at OxFF must be used. In this case the corresponding interface type is undefined. In addition to the above common characteristics table, a given module will typically have a set of sub-tables that are chained off the common table: - Service-specific characteristics table: This table contains descriptive information and parameters about the module. - Service-specific status table: This table contains runtime operating status and statistics for the module. - Upper dispatch table: This table contains dispatch addresses for the upper boundary of the module - i.e., the entry points it exports as a service provider. - Lower dispatch table: This table contains dispatch addresses for the lower boundary of the module - i.e., the entry points it exports as a service client. NOTE: Under OS/2 dispatch addresses and data segments are Ring 0 selectors. This field is usually set at Ring 3 INIT time even though the selector set must be Ring 0. MAC Service-Specific Characteristics All MAC's use the following format for this table. This table contains volatile information (like the current station address) which may be updated by the MAC during the course of operation. Other modules may read this table directly during execution. WORD Length of MAC service-specific characteristics table BYTE [16] Type name of MAC, ASCIIZ format: 802.3, 802.4, 802.5, 802.6, DIX, DIX+802.3, APPLETALK, ARCNET, FDDI, SDLC, BSC, HDLC, ISDN WORD Length of station addresses in bytes BYTE [16] Permanent station address BYTE [16] Current station address DWORD Current functional address of adapter (0 if none) LPBUF Multicast Address List (structure defined below) DWORD Link speed (bits/sec) DWORD Service flags, a bit mask: 0 - broadcast supported 1 - multicast supported 2 - functional/group addressing supported 3 - promiscuous mode supported 4 - software settable station address 5 - statistics are always current in service-specific status table 6 - InitiateDiagnostics supported 7 - Loopback supported 8 - Type of receives 0 - MAC does primarily ReceiveLookahead indications 1 - MAC does primarily ReceiveChain indications 9 - IBM Source routing supported 10 - Reset MAC supported 11 - Open / Close Adapter supported 12 - Interrupt Request supported 13 - Source Routing Bridge supported 14 - GDT virtual addresses supported 15 - Multiple TransferDatas permitted during a single indication (V2.0.1 and later) 16 - Mac normally sets FrameSize = 0 in ReceiveLookahead (V2.0.1 and later) 17-31 - Reserved, must be 0 WORD Maximum frame size which may be both sent and received DWORD Total transmission buffer capacity in the driver (bytes) WORD Transmission buffer allocation block size (bytes) DWORD Total reception buffer capacity in the driver (bytes) WORD Reception buffer allocation block size (bytes) CHAR[3] IEEE Vendor code CHAR Vendor Adapter code LPSZ Vendor Adapter description WORD IRQ Interrupt level used by adapter (V2.0.1 and later) WORD Transmit Queue Depth (V2.0.1 and later) WORD Maximum number of data blocks in buffer descriptors supported (V2.0.1 and later) Remaining bytes in table (based on Length) are vendor-specific In interpreting these tables the implementer must always bear in mind that additional functions may be added to future MAC's and that the support of functions that the protocol does not need must not prevent the protocol from accepting a bind for the MAC. The type name describes to the protocol the type of MAC protocol header that the MAC driver supports. In general, protocol stacks must be prepared to support the types "802.3", "802.5", "DIX" and "DIX+802.3". If the native media of the MAC is not one of these types (for example, ARCNET) then it is recommended that the MAC developer must consider claiming support for one of the above types and doing a transparent internal mapping between the private header format of the media and the public header format being claimed. Without support for one of the above header formats, general protocol compatibility cannot be guaranteed. The list specified above is not exhaustive. New names may be added in the future or a vendor may provide special MAC type names for use with protocols that interoperate with special MACs provided by that vendor. In the latter case it is recommended that a vendor use a MAC type name that does not start with an alphanumeric character to avoid conflicts with NDIS MAC type names that might be specified in future versions of this specification. The normal type name of an ethernet MAC would be "DIX+802.3." See Appendix B for references on IEEE 802.3 and DIX. In the various parts of this specification, all station and multicast addresses for a given MAC have the length specified in the "Length of Station Address" field. The permanent station address must be obtained from the hardware if at all possible, as it may be used by LAN Manager for security or administrative purposes. If a PROTOCOL.INI entry is used to override the current station address, the permanent station address must not be affected. Only if there is no hardware based addressing scheme will it be possible to override the permanent station address by configuration parameters. The current station address will always reflect the current address as set via parameter or by calling Request SetSetationAddress. The functional address DWORD represents the functional address bit pattern present in the last 4 bytes of an IBM compatible functional address. This excludes the first 2 bytes 0xC0, 0x00. The functional address DWORD represents the logical OR of all functional addressess currently registered to the adapters. Multicast Address List is a buffer formatted as follows: WORD Maximum number of multicast addresses WORD Current number of multicast addresses BYTE[16] Multicast address 1 BYTE[16] Multicast address 2 . . . BYTE[16] Multicast Address N The Multicast Address List is kept packed by the MAC so that the current multicast addresses occur first in the list. Service flags indicate which optional functions are supported by an NDIS driver. If a particular function bit is set, that function is supported. When attempts are made to invoke unsupported functions, NDIS MAC drivers must respond properly by returning INVALID_FUNCTION (0x0008). If loopback is supported in the network adapter hardware, then bit 7 of the MAC service flags must be set. If loopback is not supported in hardware (bit 7 of the MAC service flags is not set), the protocol driver must handle this function itself by some loopback delivery of the frame to be transmitted. The following criteria must be met for loopback: 1. The destination address is the same as the local station's current station address or the destination is a broadcast, multicast or functional address which would have been received by this station if sent by another. 2. The frame must qualify for reception according to the current packet filter. The loopback mechanism must cause the Receive indication to occur at interrupt time (and it must be delayed by IndicationOff) If IBM source routing is used (bit 9 is set) it is the protocol module's responsibility to encode and interpret appropriate source routing information. This bit merely implies that the device is capable of sending packets with the "source routing bit" set in the source address so that a protocol may recognize such a packet. While the ResetMAC function (bit 10) is optional, it is strongly recommended that those implementing the NDIS MAC driver support this function. Some protocol drivers may rely on this function to recover from hardware error conditions. If the service flags indicate that OpenAdapter is supported (bit 11 is set), then the protocol driver must ensure that the adapter is open. The open status of an adapter can be determined by examining bit 4 of the MAC status in the MAC service-specific status table. If the adapter is not open, then the protocol must issue an OpenAdapter Request (normally during bind-time processing). If Source Routing Bridge is set (bit 13) then it is implied that the MAC is capable of receiving all packets on the network which have the source routing bit set. If GDT virtual addresses are supported (bit 14 is set) then Ring 0 GDT virtual addresses may be used to describe frames. All MAC's must support the use of physical addresses to describe frames; however, for some MAC's it is preferable to supply a GDT address if one is readily available. The GDT address must remain valid throughout the scope of its use by the MAC. If bit 16 of the service flags field is set, then the MAC driver does not normally provide the total frame size of received data. In this case the MAC normally calls RecieveLookahead with the FrameSize parameter equal to 0. Setting this bit is optional. It is left to the MAC implementor to determine how frequently returning FrameSize equals 0 constitutes sufficient grounds to set this bit. However, this bit must be reset if the MAC always calls ReceiveLookahead with the FrameSize parameter non-zero or if a 0 FrameSize parameter is returned only for intermittent erroneous packet reception. For V1.0.1 compatibility, bit 16 reset gives no indication whether the MAC will return a zero FrameSize parameter or not. Some MAC and higher layer protocols do not support "length" fields within their encoding. Such protocols rely on knowing the size of valid frame data received at the MAC interface and then deduce the amount of data at their layer by stripping off the lower layer protocol headers. This bit warns such protocols that the required received frame size is not normally available at the MAC interface and that receive frames might not be able to be processed. Such protocols can refuse to bind to such MACs. The maximum frame size must reflect the maximum size packet that can be both transmitted and received by the MAC client. This size must reflect only the bytes which actually cross the NDIS boundary. For Ethernet, this value is typically 1514, since the client does not specify the CRC bytes. Token Ring values vary but do not include the non-data SD, ED and FS bytes or the FCS. The network adapter RAM is characterized by four parameters. The first is the number of bytes available for storing packets to be transmitted, usually one or two full-size packets in size. The second parameter is the allocation granularity, typically about 256 bytes, indicating how much memory would be occupied by a one byte packet pending transmission. The next two parameters are the number of bytes available for storing received packets and the receive packet granularity. Often these parameters will be affected by PROTOCOL.INI keywords (for example, specifying two transmit buffers rather than one), and it is required that these numbers accurately reflect the current adapter configuration. Protocol drivers may use these numbers to determine reasonable window sizes, and incorrect values may impact performance. The intent of the IEEE Vendor and Vendor Adapter Codes is that, when used in combination, they uniquely identify this MAC driver for this adapter. The IEEE Vendor Code uniquely defines the vendor providing the MAC driver. The use of the IEEE Vendor Code avoids the need for any global registry of Vendor Adapter Codes. The IEEE Vendor Code is assigned by the IEEE and becomes the first three bytes of a six-byte IEEE 802 address. The Vendor Adapter Code specifies a particular MAC driver provided by the Vendor for an adapter. If the IEEE Vendor Code is assigned to the Vendor, the Vendor assigns a unique Vendor Adapter Code to each MAC driver provided. For those without an IEEE Vendor Code, a value of 0xFFFFFF is required. In this case, the Vendor Adapter Code is undefined. The Vendor Adapter description string is an ASCIIZ string containing a description of the adapter that could be used to format an error message (for example, "3Com EtherLink II Adapter"). The transmit queue depth specifies the maximum number of TransmitChain requests the MAC can buffer internally. This number must be set to one if the TransmitChain implementation in the MAC is synchronous. Each queued TransmitChain request requires that the MAC driver copy at least the chain descriptor and immediate data, so this parameter is generally configurable through a PROTOCOL.INI keyword called MAXTRANSMITS. The protocol driver can use this queue depth to compute the amount of time a transmit might be queued up within the MAC. The maximum number of data buffer blocks is the maximum number of blocks supported in Transmit, TransferData, and ReceiveChain buffer desciptors. For V1.0.1 backward compatibility this must be a minimum of 8. For V1.0.1 compatible MACs for which this field is absent, the maximum number assumed is 8. The size of the NDIS defined part of the MAC specific characteristics table may increase in subsequent versions of the specification. If vendor specific information follows the NDIS defined information, a protocol using it must check the NDIS spec version number in the Common Characteristics table to determine where the NDIS specified information ends and the vendor specified information begins. MAC Service-Specific Status Table The MAC service-specific status and media-specific statistics tables provide information about the status of and traffic through a MAC. Since these tables can be updated by the MAC driver at interrupt time, a protocol must ensure that these tables are read with interrupts disabled. The MAC must update this table (and the media-specific statistics table if present) atomically. WORD Length of status table DWORD Date/time when diagnostics last run (0xFFFFFFFF if not run). Format is seconds since 12:00 Midnight January 1, 1970 DWORD MAC status, a 32-bit mask: 0-2 - Opcoded as follows: 0 - Hardware not installed 1 - Hardware failed startup diagnostics 2 - Hardware failed due to configuration problem 3 - Hardware not operational due to hardware fault 4 - Hardware operating marginally due to soft faults 5-6 Reserved 7 - Hardware fully operational 3 - If set, MAC is bound, else not bound 4 - If set, MAC is open, else not open (if adapter doesn't support open/close function, set to 1 if hardware is functional) 5 - If set, adapter diagnostics are in progress (V2.0.1 and later) 6-31 - Reserved, must be zero WORD Current packet filter, a bit mask: 0 - directed and multicast or group and functional 1 - broadcast 2 - promiscuous 3 - all source routing 4-15 - Reserved, must be zero Statistics for MAC's Statistics in bold are mandatory, all others are strongly recommended, 0xFFFFFFFF means not supported. Reserved slots should return as 0xFFFFFFFF (unsupportd). LPBUF Pointer to media specific statistics table (may be NULL) DWORD Date/time when last ClearStatistics issued (0xFFFFFFFF if not kept) format is seconds since 12:00 Midnight January 1, 1970 DWORD Total frames received OK DWORD Total frames with CRC error DWORD Total bytes received DWORD Total frames discarded - no buffer space DWORD Total multicast frames received OK DWORD Total broadcast frames received OK DWORD Reserved (Obsolete statistic) DWORD Reserved (Obsolete statistic) DWORD Reserved (Obsolete statistic) DWORD Reserved (Obsolete statistic) DWORD Reserved (Obsolete statistic) DWORD Total frames discarded - hardware error DWORD Total frames transmitted OK DWORD Total bytes transmitted OK DWORD Total multicast frames transmitted DWORD Total broadcast frames transmitted DWORD Reserved (Obsolete statistic) DWORD Reserved (Obsolete statistic) DWORD Total frames not transmitted - time-out DWORD Total Frames not transmitted - hardware error Remaining bytes (based on Length) in table are vendor specific. All statistics counters are 32-bit unsigned integers that wrap to zero when the maximum count is reached after which the counters will continue to count. When updating these counters, a frame is counted in all the supported counters that apply. The case of an unsupported counter (0xFFFFFFFF) can be distinguished from the situation wherby a counter is about the wrap around if the values of the counters are checked at bind times. If the initial value of the counter is 0xFFFFFFFF, then the counter is not supported. Otherwise the counter is supported and 0xFFFFFFFF at a later time means the counter is about to wrap around. SERVICE SPECIFIC STATISTICS DEFINITIONS: Total frames received ok (NumberOfFramesReceivedOK) - corresponding 802.3 statistics This contains a count of frames that are successfully received. It does not include "frames with errors", as listed in non-media specific statistics item 7. Frames received with CRC error This contains a count of frames that are an integral number of bytes in length and do not pass the FCS check. Reports on CRC errors "as the station sees it". Total bytes received ok This contains a count of bytes in frames that are successfully received. It includes bytes from received multicast and broadcast frames. This number should include everything, starting from destination address up to but excluding FCS. Source address destination address, length (or type) and pad are included. It should exclude FCS and the preambles. According to this definition, this NDIS statistics is not exactly the same as 802.3's NumberOfBytesReceivedOK, which does not include the octets in the address and length/type fields. Frames discarded - no buffer space Frames discarded by MAC driver due to a lack of buffer space. Multicast frames received ok. (NumberOfMulticastFramesReceivedOK) This includes all of the multicast frames the MAC driver received successfully. It does not include "frames with errors" as listed in non-media specific statistics item 7. Broadcast frames received ok. (NumberOfBroadcastFramesReceivedOK) This includes all of the broadcast frames the MAC driver receives successfully. It does not include "frames with errors" as listed in non-media specific statistics item 7. Frames discarded - hardware error Frames discarded due to hardware error. Definition of this statistic should be adapter spacific. Total frames transmitted ok. (NumberOfFramesTransmittedOK) Total number of frames transmitted successfully. Total bytes transmitted ok. Total number of bytes transmitted successfully. This number should include everything, starting from destination address up to but excluding FCS. Source address destination address, length (or type) and pad are included. It should exclude FCS and the preambles. Multicast frames transmitted ok. (NumberOfMulticastFramesTransmittedOK) Number of frames transmitted successfully to non-broadcast group address. Broadcast frames transmitted ok. (NumberOfBroadcastFramesTransmittedOK) Number of frames transmitted successfully to broadcast address. Frames not transmitted - time-out This contains a count of frames that could not be transmitted due to the hardware not signaling transmission completion for an excessive period of time. Frames not transmitted - hardware error This contains a count of frames that could not be transmitted due to a hardware error. This count should exclude DMA underrun error which itself is a separate counter (Frames transmitted with underun). Definition of this statistic should be adapter specific. MAC Upper Dispatch Table The number and meaning of dispatch addresses provided here apply to the boundary between a MAC and a protocol. This may differ at other protocol boundaries. Note that each upper/lower module binding may have its own unique set of dispatch addresses that is set up when the modules exchange characteristics tables. This can be achieved by exchanging copies of the common characteristics table, where the copy has the desired pointers to the specific dispatch tables for the binding. LPBUF Back pointer to common characteristics table LPFUN Request address LPFUN TransmitChain address LPFUN TransferData address LPFUN ReceiveRelease address LPFUN IndicationOn address LPFUN IndicationOff address NOTE: No dispatch address is allowed to be NULL. Protocol Service-Specific Characteristic Table For compatibility with future versions of this specification, all protocols must provide a protocol service-specific characteristics table which starts with the following fields: WORD Length of protocol service-specific characteristics table BYTE [16] Type name of protocol, ASCIIZ format: WORD Protocol type code This may be followed by protocol-specific information. The protocol type name will be used in future versions of this specification. Specific type names for different protocol types will be defined later. Protocol type codes will also be defined later. For the moment these two fields are simple place holders and must be set to null string and zero respectively. Protocol Lower Dispatch Table The protocol lower dispatch table is specified in the characteristics table for the protocol binding to the MAC. The characteristics table for the MAC actually does not supply a lower dispatch table (the pointer to it is NULL). LPBUF Back pointer to common characteristics table DWORD Interface flags (used by Vector frame dispatch): 0 - Handles non-LLC frames 1 - Handles specific-LSAP LLC frames 2 - Handles non-specific-LSAP LLC frames 3-31 - Reserved must be zero LPFUN RequestConfirm address LPFUN TransmitConfirm address LPFUN ReceiveLookahead indication address LPFUN IndicationComplete address LPFUN ReceiveChain indication address LPFUN Status indication address NOTE: No dispatch address is allowed to be NULL. Characteristic Tables for NetBIOS Drivers NetBIOS drivers written to the existing LAN Manager Ring0 NetBIOS specification can be adapted to fit into the Protocol Manager structure by defining a common characteristics table for them shown below. Note that such a NetBIOS driver must still respond to the existing LAN Manager NetBIOS Linkage binding mechanism; these drivers will only use Protocol Manager binding at their lower boundary (to the MAC). A variant kind of NetBIOS module will be defined in the future that takes advantage of Protocol Manager binding at both boundaries. Common characteristics for NetBIOS drivers: WORD Size of common characteristics table (bytes) BYTE Major NDIS Version (2 BCD digits) BYTE Minor NDIS Version (2 BCD digits) WORD Reserved BYTE Major Module Version (2 BCD digits) BYTE Minor Module Version (2 BCD digits) DWORD Module function flags, 0x00000002 (binds lower) BYTE[16] NetBIOS Module name BYTE Protocol level at upper boundary of module: 5 = Session BYTE Type of interface at upper boundary of module: 1 = LANMAN NCB BYTE Protocol level at lower boundary of module: 1 = MAC BYTE Type of interface at lower boundary of module: 1 = MAC WORD NetBIOS Module ID WORD NetBIOS Module DS LPFUN System request dispatch entry point LPBUF Pointer to service-specific characteristics (see below) LPBUF Pointer to service-specific status, must be (NULL) LPBUF Pointer to upper dispatch table (see below) LPBUF Pointer to lower dispatch table (see below) LPBUF Reserved, must be NULL LPBUF Reserved, must be NULL Upper dispatch table for a NetBIOS module: LPBUF Back pointer to common characteristics table LPFUN Request address LPFUN NetBIOS NCB handler (LANMAN calling conventions) Lower dispatch table for a NetBIOS module: LPBUF Back pointer to common characteristics table DWORD Interface flags (used by Vector frame dispatch): 0 - Handles non-LLC frames 1 - Handles specific-LSAP LLC frames 2 - Handles non-specific-LSAP LLC frames 3-31 - Reserved must be zero LPFUN RequestConfirm address LPFUN TransmitConfirm address LPFUN ReceiveLookahead indication address LPFUN IndicationComplete address LPFUN ReceiveChain indication address LPFUN Status indication address Service-specific characteristics for a NetBIOS module: WORD Length of NetBIOS module service-specific characteristics table BYTE [16] Type name of NetBIOS module, ASCIIZ format: WORD NetBIOS module type code This may be followed by module-specific information. The protocol type name will be used in future versions of this specification. Specific type names for different protocol types will be defined later. Protocol type codes will also be defined later. For the moment these two fields are simple place holders and must be set to null string and zero respectively. Frame Data Description The MAC describes frame data with a data structure called a buffer descriptor. The descriptor is composed of pointers and lengths which describe a logical frame. Buffer descriptors are ephemeral objects. A descriptor is valid only during the scope of the call that references it as a parameter. The called routine must not modify the descriptor in any way. If the called routine needs to refer to the described data blocks after returning from the call, it must save the information contained in the descriptor. Data blocks described by descriptors are long-lived. Ownership of the data blocks is implicitly passed to the module that is called with the descriptor. The called module relinquishes ownership back to the caller either via setting a return argument, or by later issuing a call back to the supplying module. Under OS/2, some pointers may be either GDT virtual addresses or physical addresses. In this case the pointer has an associated pointer type opcoded field. Defined values are 0 for physical address and 2 for GDT virtual addresses. GDT virtual addresses may be supplied to the MAC only if bit 14 of the service flags in the MAC service specific characteristics table is set. The GDT address must remain valid throughout the scope of its use by the MAC. Under DOS there is no distinction between physical and virtual addresses. All addresses in this case are segment: offset. Care must be taken to ensure that the segment offset plus data length do not exceed the 64K segment boundary. The pointer type field if present is always encoded as a 0. For performance reasons, it is recommended that data blocks used for transmission and reception be double-word aligned where possible. Both MAC and protocol NDIS drivers may choose to perform byte, word or dword memory movement without first ensuring proper alignment. This will result in reduced performance in combination with drivers which do not guarantee such alignment. A buffer descriptor may contain one or more data blocks of length zero. In this case the other fields in the data block (Data Ptr and Data Type) may not be valid and must be ignored. Transmit Buffer Descriptor All transmit data is passed using a far pointer to a transmit buffer descriptor, TxBufDescr. The format of this descriptor is: WORD TxImmedLen ;Byte count of immediate data; max is 64 LPBUF TxImmedPtr ;Virtual address of immediate data WORD TxDataCount ;Count of remaining data blocks; max is configurable Followed by TxDataCount instances of: BYTE TxPtrType ;Type of pointer (0=Physical, 2=GDT) BYTE TxResByte ;Reserved Byte (must be 0) WORD TxDataLen ;Length of data block LPBUF TxDataPtr ;Address of data block In a TxBufDescr structure, the immediate data described by the first two fields is ephemeral and may be referenced only during the scope of the call that supplies it. Such immediate data is always transmitted before data described by TxDataLen and TxDataPtr pairs. If the called routine needs to refer to the immediate data after returning from the call, it must copy the data. The maximum size of immediate data is 64 bytes. For V2.0.1 MACS or later the maximum TxDataCount is specified in the MAC specific characteristics table. For V1.0.1 MACs the maximum count is 8. Transfer Data Buffer Descriptor Transfer data can be described by a far pointer to a transfer data buffer descriptor, TDBufDescr. Transfer data buffer descriptors have the following format: WORD TDDataCount ;Count of transfer data blocks; max is configurable Followed by TDDataCount instances of: BYTE TDPtrType ;Type of pointer (0=Physical, 2=GDT) BYTE TDResByte ;Reserved Byte (must be 0) WORD TDDataLen ;Length of data block LPBUF TDDataPtr ;Address of data block For V2.0.1 MACs or later the maximum TDDataCount is specified in the MAC specific characteristics table. For V1.0.1 MACs the maximum count is 8. Receive Chain Buffer Descriptor Receive chain data can be passed by a far pointer to a receive chain buffer descriptor, RxBufDescr. Receive chain buffer descriptors have the following format: WORD RxDataCount ;Count of receive data blocks; max is configurable Followed by RxDataCount instances of: WORD RxDataLen ;Length of data block LPBUF RxDataPtr ;Virtual address of data block For V2.0.1 MACs or later the maximum receive data block count is specified in the MAC specific characteristics table. For V1.0.1 MACs the maximum count is 8. For received frames that are larger than 256 bytes, the first data block of the frame must be at least 256 bytes long. Frames less than or equal to 256 bytes will be passed up with RxDataCount equal to 1. PROTOCOL.INI The PROTOCOL.INI file stores configuration and binding information for all the protocol and MAC modules in the system. The file uses the same general format as the LANMAN.INI file. It consists of a series of named sections, where the section name is in fact the module name from a module characteristics table. Below the bracketed module name is a set of configuration settings for the module in name=value format. For example: [MYNetBIOS] Drivername = NetBIOS$ Bindings = ETHERCARD MaxNCBs = 16 MaxSessions = 32 MaxNames = 16 The rules for PROTOCOL.INI contents are: - Bracketed module name. Must be the name of a protocol or MAC module, e.g. [MYNetBIOS]. This is the name of the module as defined in that module's characteristics table. The name must be 15 characters or less (not counting the brackets). Mixed case may be used but the Protocol Manager will convert it to uppercase when it reads the file into memory. - Drivername = . This parameter is required for all device driver modules. It defines the name of the OS/2 or DOS device driver that the module is contained in. Note that a single device driver name may be mentioned by several sections of the PROTOCOL.INI file, if the driver contains multiple logical modules. The Drivername parameter is the recommended method by which a module searches for its module section in the PROTOCOL.INI file to get its configuration parameters. This allows the module to find all relevant module sections based on a single name intrinisic to the module independent of the particular bracketed module name used in the PROTOCOL.INI file. This keyword is also required for DOS dynamic modules like TSRs or transient application modules. Although there is no driver name instrinsically assigned to such modules it is required that a unique name be assigned to this keyword for such modules anyway. In this way the same search mechanism used by device drivers can be used by dynamic DOS modules to find their relevant module sections in PROTOCOL.INI. - Bindings = | ,, . . . This parameter is optional for protocol modules. It is not valid for MAC modules. If present, it is used by the protocol module to determine what MAC modules it will ask to bind to. (In other words, changing this parameter in the PROTOCOL.INI file can reconfigure a protocol to bind to a different MAC.). The Bindings parameter may be omitted if the protocol driver software is preconfigured to bind to a particular MAC, or if the system will only contain one MAC and one static protocol module. In the latter case (only in static mode), the Protocol Manager by default will ask the one static protocol to bind to the one MAC. - Other keywords and parameters. Any other keyword=value statements are module specific. Keyword names must be 15 characters or less. They may be mixed case but are converted to uppercase when read by the Protocol Manager. Note that keyword names are unique within the scope of each section and can appear within the section in any order. - Whitespace around the equals sign is not significant, nor is trailing white space on the line. Except for this leading and trailing white space, all other characters of the value string are taken verbatim. - A list of 0 or more parameters can appear to the right of the equals sign. If there are no parameters the equals sign can be optionally omitted. A parameter is terminated by a space, tab, comma, or semicolon. No parameters are interpreted by the Protocol Manager. - A parameter can either be up to a 31-bit signed numeric value or a string of any length. - A numeric parameter can be expressed either in decimal or hexadecimal format. All numeric parameters must start with the characters '0' through '9' or by a + or - followed by the '0' to'9' character. A hexadecimal parameter must start with '0x' or '0X' and use valid hexadecimal digits. A non-hexadecimal numeric parameter is treated as decimal integer. A parameter not surrounded by quotes and starting with 0 to 9 or + and - followed by 0 to 9 will be assumed to be a numeric parameter. - A string is a parameter which either starts with a non-numeric character or is surrounded with quotes ("...."). The string is preserved in the memory image as it appears in PROTOCOL.INI. - A line starting with a semicolon in column 1 is a comment and is ignored. Blank lines are ignored too. - Lines may be as long as required. Continuation lines are not supported. Lines end with CR LF. - Tabs, formfeeds, and spaces are considered to be white space. The Protocol Manager supports an optional section with optional keywords defined below: [PROTMAN] Drivername = PROTMAN$ Dynamic = YES or NO PRIORITY = prot1, prot2, ... Bindstatus = YES or NO The bracketed module name can be any valid name as long as it is unique within this PROTOCOL.INI. Drivername is required and must be assigned PROTMAN$, identifying the section as belonging to the Protocol Manager. None of the entries are case-sensitive. The DYNAMIC keyword is optional. It defaults to NO if not present. If set to NO, the Protocol Manager operates only in the static mode and does not support dynamic protocol drivers. If set to YES, the Protocol Manager operates in the dynamic mode and supports both static and dynamic binding. The PRIORITY keyword is optional. If absent, then the VECTOR uses default demultiplexing priority if multiple protocol drivers are bound to the same MAC (see Vector Demultiplexing in Chapter 7). If present, the parameters on the right-hand side are presumed to be a list of protocol module names, highest priority first. The VECTOR prioritizes protocol drivers for demultiplexing (if necessary) according to their order in the list, and packets are offered to the first protocol driver listed first. Protocol drivers not listed are assigned default priority AFTER those listed. It is not necessary that a protocol driver ever bind for it to be listed here. The BINDSTATUS keyword is optional. If absent, then the BindStatus command is not supported by the Protocol Manager. If set to YES, then BindStatus is supported by the Protocol Manager. The default disable condition is a memory optimization feature primarily for DOS environments. When syntax errors are detected in processing the PROTOCOL.INI commands, by convention, all NDIS drivers should: 1) Display a error message detail exact syntax problem. 2) Assume some non-fatal value for the parameter associated with the error and complete processing. Configuration Memory Image When the Protocol Manager initializes, it reads PROTOCOL.INI and parses it into a memory image that it makes available to MAC and protocol modules via the Get Protocol Manager Info call. The parsed image is formatted to make it easy for run-time modules to interpret. All information contained in PROTOCOL.INI is present in the memory image in the same order as in the file. (Comments and white space are of course not present in the image). Note that in static mode the image is only available during device driver initialization time. In dynamic mode the image may additionally be created by a utility which then registers it with the Protocol Manager. The structure definitions defined below do not conform rigorously to C language syntax. They provide a pseudo C-like language to define the data structures encoded in the configuration memory image. ConfigMemoryImage The ConfigMemoryImage data structure defines the complete memory image for all logical devices read from the PROTOCOL.INI configuration file. It is a doubly linked list of ModuleConfig structures. Each ModuleConfig structure corresponds to one module. The ConfigMemoryImage structure is defined as follows: struct ConfigMemoryImage { struct Module Config(1) Module(1); struct Module Config(2) Module(2); . . . struct ModuleConfig(N) Module(N); }; where: N=the number of modules encountered by the Protocol Manager when parsing the configuration file PROTOCOL.INI. ModuleConfig The ModuleConfig(i) structure defines the memory image for configuration parameters corresponding to one (bracketed name) module. For the (i)th module specified in PROTOCOL.INI it is defined as follows: struct ModuleConfig(i) { struct ModuleConfig(i+1) far *NextModule; struct ModuleConfig(i-1) far *Prev Module; unsigned char Module Name [16]; struct KeywordEntry(1) KeywordEntry(1); struct KeywordEntry(2) KeywordEntry(2); . . . struct KeywordEntry(N) KeywordEntry(N); }; where: N = the number of keyword entries encountered in the PROTOCOL.INI file for this module. NextModule = a FAR pointer to the next module configuration structure. NULL if this is the structure for the last module. For OS/2 the selector is a Ring 3 selector. For DOS the pointer is a segment:offset pair. PrevModule = a FAR pointer to the previous module configuration structure. NULL if this is the structure for the first module. For OS/2 the selector is a Ring 3 selector. For DOS the pointer is a segment:offset pair. ModuleName = array containing the characters of the module name (given in brackets in the configuration file). This is an ASCIIZ string consisting of a maximum of 15 non-null uppercase characters. KeywordEntry For each keyword line in the configuration file for the module a memory image structure is created specifying the keyword and the parameter values. The (j)th keyword encountered in the PROTOCOL.INI file for the module is defined as follows: struct KeywordEntry(j) { struct KeywordEntry(j+1) far *NextKeywordEntry; struct KeywordEntry(j-1) far *PrevKeywordEntry; unsigned char Keyword[16]; unsigned NumParams; struct Param(1) Param(1); struct Param(2) Param(2); . . . struct Param(N) Param(N); }; where: N = the number of parameters entered with the keyword. If N =0 the parameters are not present. NextKeywordEntry = a FAR pointer to the next keyword entry structure in the memory image. NULL if this is the last keyword entry. For OS/2 the selector is a Ring 3 selector. For DOS the pointer is a segment:offset pair. PrevKeywordEntry = a FAR pointer to the previous keyword entry structure in the memory image. NULL if this is the first keyword entry. For OS/2 the selector is a Ring 3 selector. For DOS the pointer is a segment:offset pair. Keyword = the array containing the characters of the keyword found in the configuration file. This is an ASCIIZ string consisting of a maximum of 15 non-null characters. The case of alphabetic characters will be uppercase in the memory image. NumParams = the number (N) of parameters entered with the keyword each parameter described by a param structure. The value is 0 if no parameters were present. Param(k) = the (k)th parameter structure to specify the value of one parameter in a list of parameters for a keyword. "Param(k+1)" follows Param(k) in sequence within the memory image. Each parameter is delimited by a length field for the parameter. It is assumed that a keyword's fields will be parsed sequentially. Param For the (k)th parameter defined in a parameter list for a specific keyword the following structure defines its value and attributes: struct Param(k) { unsigned ParamType; unsigned ParamLen; union ParamValue { long Numeric; unsigned char String[STRINGLEN]; }; }; where: STRINGLEN = length of the ASCIIZ parameter string (including the terminating NULL) for string parameters. ParamType = the type of parameter. The following types are supported: 0 - signed integer supporting up to 31 bit values least significant byte first. 1 - a string of characters. ParamLen = the length of the parameter value. The length could be one of the following either be 4 for numeric parameters or STRINGLEN for string parameters where STRINGLEN is the length of the string (including the terminating NULL). Numeric = a 31-bit signed numeric value. String = an ASCIIZ character string. The case of alphabetic characters in the string is preserved from that in PROTOCOL.INI. The size of the Param (k) structure is thus ParamLen + 4. BindingsList For each module that registers with the Protocol Manager a BindingsList structure may be given to the Protocol Manager specifying the set of modules that the given module wishes to bind to. The current module will require services from these other modules. This structure is defined as follows: struct BindingsList { unsigned NumBindings; struct Module { char ModuleName[16]; } BoundDriver[NUMBINDINGS]; }; where: NumBindings = the number (NUMBINDINGS) of modules that the specified module wants to be bound to it from below. In the static default binding mode of one static protocol and one MAC, a value of 0 in this field means for the protocol that it will bind to the MAC. Otherwise in the non-default binding mode, a value of 0 in this field means that the module has no lower bindings. ModuleName = an ASCIIZ string specifying the logical name of a module which the current module wishes to have bound to it from below. Maximum of 15 non-null characters. The Protocol Manager will convert all alphabetic characters to uppercase. BoundDriver = an array of NUMBINDINGS module names specifying the list of modules to which the current module wants to be bound. The order of the modules in the list is significant in that InitiateBind requests will be issued to the protocol module in this order. Chapter 5: Specification of Primitives Implementers should obey the following general guidelines: - All primitives specified in this section can be called in protected mode in either interrupt or task context under OS/2. Since any primitive may be called in interrupt context it is illegal to block during the execution of a primitive. - All routines must run (as much as possible) with interrupts enabled. Interrupt handlers must dismiss the interrupt at the 8259 as soon as possible. - An indication handler will normally be entered with interrupts enabled. The handler may enable or disable interrupts if it chooses and on return the MAC must assume that the interrupt state may have been changed. - Under MS-DOS indication handlers must assume they have only 200 bytes of stack space. If more stack space is needed then the handler must supply a stack. - Confirmation and IndicationComplete handlers must be fully re- entrant and are always entered with interrupts enabled. Under DOS Confirmation and IndicationComplete handlers must assume they are entered on whatever stack the interrupt occurred on. - A confirmation handler may be entered with the confirmation for a request before the request has returned. - It is recommended that a MAC release the internal resources associated with either TransmitChain or a request before calling the confirmation handler. This allows the protocol to submit a new TransmitChain or request from the confirmation handler. Failing to do so may have a significant impact on performance. - A protocol must assume whenever it gives control to a MAC that interrupts may be enabled by the MAC unless otherwise explicitly specified. - When passing a virtual address to one of these primitives under OS/2 the address must be a Ring 0 GDT address unless otherwise specified. The interrupt service routine portion of the MAC must handle the fact that this address may not be valid if an interrupt occurs in real mode. - All primitives have a set of specific error codes defined. In general, MAC's and protocols must return these specific codes. However it is acceptable to return GENERAL_FAILURE for any non- recoverable failure. NDIS developers must be aware that new error codes may be added in the future and must design their code to allow for this. - If a particular entry point or function is not supported by an NDIS protocol or MAC driver, the entry point must still be exposed and an error (INVALID_FUNCTION 0x0008) returned if it is called. Crashing when an unsupported request is made is unacceptable. - Parameters are passed on the stack compatible with Microsoft C FAR Pascal calling conventions. On entry to any routine the called module must save the caller's DS before setting its DS from the "dataseg" parameter. At exit the caller's DS must be restored. Furthermore the called module must follow standard Microsoft C conventions about saving "register variable" SI and DI registers if these are used. Modules which use the 80386 registers EDI, ESI and EBP must preserve these registers also. The direction bit is assumed to be clear on entry and must be clear upon exit. These conventions apply for calls in both directions across the NDIS MAC interface. - Direct calls return in AX a return code specifying the status of function invocation. Those functions specified as using IOCTLs return this in the status field of the request block. - Before calling a module in OS/2 it is the caller's responsibility to ensure that it is currently executing in protected mode. If it is running in real mode it must do an OS/2 "RealToProt" DevHlp call before calling the inter-module interface function. Furthermore in OS/2 the inter-module call can only be made at post CONFIG.SYS INIT time since all selectors are Ring 0 selectors. - A MAC starts with packet reception disabled. A protocol must call SetPacketFilter to enable reception of packets. - It is recommended that the number of Request commands which can be simultaneously queued by the MAC be configurable. The suggested keyword in the configuration file is "MaxRequests." The recommended default is 6. The suggested range is 1 to 10. - The number of TransmitChain commands which can be simultaneously queued by the MAC must be configurable. The suggested keyword in the configuration file is "MaxTransmits". The recommended default is 6. The suggested range is 1 to 50. - On a DIX or 802.3 network, packet buffers received may have been padded to the minimum packet size for short packets. It is the responsibility of the MAC client to examine the length field if present and strip off the padding. - For DIX or 802.3 networks the MAC client can transmit a buffer with packet length smaller than the minimum. It is the responsibility of the MAC to provide the required padding bytes before transmission on to the wire. The content of the padding bytes is undefined. - Protocol drivers conforming to this specification are expected to format and interpret MAC headers for the MAC driver types supported. Generally, protocols are expected to support 802.3, DIX, and 802.5 MAC headers. It is recommended that MAC drivers for other media types consider claiming to be one of the above types and doing a transparent internal mapping between that and its own private MAC header format. In doing so, the MAC will be able to claim interoperability (assuming the appropriate testing is done) with most protocol drivers developed for LAN Manager. - In the absence of any such conversion, the MAC header is passed protocol-to-MAC or MAC-to-protocol in exactly the format in which it exists on the medium. The CRC and non-data fields are not passed across this boundary. Therefore the Ethernet CRC and the Token Ring SD, FCS, ED and FS fields are not passed and will not be included in the packet length. The protocol must convert header fields found in the header buffer passed up to whatever format is required to conveniently store them in local memory. For example multi-byte fields (e.g., 802.3 length) may not be received in the byte order that is normally used by the CPU for storing multi-byte parameters. For exact format of the MAC header refer to the appropriate standards document (see Appendix B). - For performance reasons, it is recommended that PhysToGDT be used whenever possible instead of PhysToVirt. - Commonly Used Parameters ProtID The unique module ID of the protocol, assigned at bind time by the Protocol Manager. MACID The unique module ID of the MAC, assigned at bind time by the Protocol Manager. ReqHandle A handle assigned by the protocol to identify this request. If the request is implemented asynchronously by the MAC driver in question, this handle is returned on the confirmation call used to indicate completion of the request. A ReqHandle of 0 indicates that the confirmation be unconditionally suppressed. For example, the request may still be handled asynchronously but there will be no notification of completion. A ReqHandle of 0 must not change the immediate return code. ProtDS DS value for called protocol module, obtained from the module's dispatch table at bind time. MACDS DS value for called MAC module, obtained from the module's dispatch table at bind time. Direct Primitives TransmitChain Purpose: Initiate transmission of a frame PUSHWORD ProtID ;Module ID of protocol PUSHWORD ReqHandle ;Unique handle for this request or 0 PUSHLPBUF TxBufDescr ;Pointer to framebufferdescriptor PUSHWORD MACDS ;DS of called MAC module CALL TransmitChain Returns: 0x0000 SUCCESS 0x0002 REQUEST_QUEUED 0x0006 OUT_OF_RESOURCE 0x0007 INVALID_PARAMETER 0x0008 INVALID_FUNCTION 0x000A HARDWARE_ERROR 0x000B TRANSMIT_ERROR 0x000C NO_SUCH_DESTINATION 0x00FF GENERAL_FAILURE TxBufDescr Far pointer to the buffer descriptor for the frame. Description: This call asks the MAC to transmit data. The MAC may either copy the data described by TxBufDescr before returning, or queue the request for later (asynchronous) processing. The MAC indicates which option it is taking by setting the appropriate return code. In the asynchronous case, ownership of the frame data blocks passes to the MAC until the transmission is complete; the protocol must not modify these areas until then. Ownership of the data blocks is returned to the protocol when the MAC either returns a status code which implies completion of the original request or calls its TransmitConfirm entry with the ReqHandle from TransmitChain. If a request handle of zero was used and therefore TransmitConfirm will not be called, then ownership must not be considered returned until the protocol receives a message that implies the transmission has occurred (e.g., receiving an ACK to the transmitted message). Note that when doing asynchronous transmission, the MAC must retain any needed information from TxBufDescr, since the pointer to that structure becomes invalid upon returning from TransmitChain. Also, if the TxImmedLen of the descriptor is non- zero, the MAC must retain a copy of the immediate data at TxImmedPtr, since the immediate data area becomes invalid upon returning from TransmitChain. The MAC header must fit entirely in the immediate data, if present, or in the first non-immediate element described in TxBufDescr if there is no immediate data. A MAC must be prepared to handle a TransmitChain request at anytime, including from within interrupt-time indication routines. The return code REQUEST_QUEUED will cause a TransmitConfirm to be called from the MAC back to the protocol if the ReqHandle on the TransmitChain call is not 0. All other return codes from TransmitChain imply that no TransmitConfirm will occur. The TRANSMIT_ERROR and NO_SUCH_DESTINATION error codes are intended to allow a protocol to recreate the frame status byte on a Token Ring network. Thus, NO_SUCH_DESTINATION implies that the address recognized bits were not set (and therefore the frame was not copied), while TRANSMIT_ERROR merely means that the frame was not copied. Protocols which make use of Source Routing may need the NO_SUCH_DESTINATION error code to be completely conformant. Token Ring MAC driver writers must make every attempt to return these error codes properly. TransmitConfirm Purpose: Imply the completion of transmitting a frame. PUSH WORD ProtID ;Module ID of Protocol PUSH WORD MACID ;Module ID of MAC PUSH WORD ReqHandle ;Unique handle from TransmitChain PUSH WORD Status ;Status of original TransmitChain PUSH WORD ProtDS ;DS of called protocol module CALL TransmitConfirm Returns: 0x0000 SUCCESS 0x0007 INVALID_PARAMETER 0x00FF GENERAL_FAILURE Description: This routine is called by a MAC to indicate completion of a previous TransmitChain. The purpose of this is to return ownership of the transmitted data blocks back to the protocol. The ProtID parameter must be the value passed by the protocol on the previous TransmitChain to identify the requestor. The ReqHandle is the value passed by the protocol on the previous TransmitChain which identifies the original request. TransmitConfirm does not necessarily imply that the packet has been transmitted, though it generally will have been (with the exception of some intelligent adapter implementations). If the packet has been transmitted, Status must indicate the final transmit status: 0X0000 SUCCESS 0X000A HARDWARE_ERROR 0X000B TRANSMIT_ERROR 0X000C NO_SUCH_DESTINATION 0X00FF GENERAL_FAILURE See TransmitChain for more details. ReceiveLookahead Purpose: Indicate arrival of a received frame and offer lookahead data. PUSH WORD MACID ;Module ID of MAC PUSH WORD FrameSize ;Total size of frame (0 if not known) PUSH WORD BytesAvail ;Bytes of lookahead available in Buffer PUSH LPBUF Buffer ;Virtual address of lookahead data PUSH LPBYTE Indicate ;Virtual address of indicate flag PUSH WORD ProtDS ;DS of called protocol module CALL ReceiveLookahead Returns: 0x0000 SUCCESS 0x0003 FRAME_NOT_RECOGNIZED 0x0004 FRAME_REJECTED 0x0005 FORWARD_FRAME 0x0006 OUT_OF_RESOURCE 0x0007 INVALID_PARAMETER 0x00FF GENERAL_FAILURE FrameSize The total size, in bytes, of the received frame. A value of 0 indicates that the MAC does not know the total frame size at this time. BytesAvail The number of bytes available in the lookahead buffer. This is guaranteed to be at least as large as the lookahead size established with the SetLookahead request. For frames which are smaller than the lookahead size, the lookahead buffer will contain the whole frame. Buffer Virtual address of contiguous lookahead buffer. The buffer contains the leading BytesAvail octets of the frame. This buffer is ephemeral; it is addressable to the protocol only during the scope of the Receive call. Indicate Virtual address of indication flag byte. This byte is set to 0xFF by the MAC prior to this call. If the protocol clears the byte to zero prior to returning then indications will be left disabled until IndicationOn is called from IndicationComplete. Description: This routine is called by a MAC to indicate reception of a frame and to offer frame lookahead data. The protocol is expected to inspect this information very rapidly to determine if it wants to accept the frame or not. If it wants to accept the frame, it may call TransferData to ask the MAC to copy the frame data to a specified buffer described by a TDBufDescr. The protocol can indicate that it is rejecting or does not recognize the frame by returning an appropriate error code. Note that the frame not recognized error has special significance to the Vector function. If the protocol is accepting the frame and if the lookahead buffer contains the whole frame, the protocol can simply copy the data itself before returning from Receive. The protocol may determine that it has the whole frame if BytesAvail equals FrameSize, or if the lookahead information includes a protocol header with the frame length, and this matches BytesAvail. It is strongly recommended that MACs provide a non-zero FrameSize whenever possible. Some protocols might not be able to process frames unless the frame size given by this parameter is known. A MAC can optionally indicate that it does not normally provide a non-zero frame size by setting bit 16 of the service flags in the MAC specific characteristics table. The MAC implicitly disables indications (IndicationOff) before calling Receive Lookahead. The Indicate flag byte instructs the MAC on whether to reenable indications or leave them disabled on the return. If the protocol chooses to leave indications disabled, it can enable them within IndicationComplete by calling IndicationOn. The protocol must absolutely minimize its processing time within the ReceiveLookahead handler. This is necessary to let certain MAC's re-enable the hardware to avoid loss of incoming frames. Shortly after returning from ReceiveLookahead, the MAC will call the protocol back at its IndicationComplete entry point. The protocol can do any needed post-processing of the received frame at that time. The MAC does not guarantee to provide one IndicationComplete call for each indication. It can choose to issue a single IndicationComplete for several indications that have occurred. TransferData Purpose: Transfer received frame data from the MAC to a protocol. PUSH LPWORD BytesCopied ;Number of bytes copied PUSH WORD FrameOffset ;Starting offset in frame for transfer PUSH LPBUF TDBufDescr ;Virtual address of transfer data description PUSH WORD MACDS ;DS of called MAC module CALL TransferData Returns: 0x0000 SUCCESS 0x0007 INVALID_PARAMETER 0x0008 INVALID_FUNCTION 0x00FF GENERAL_FAILURE BytesCopied Virtual address of buffer for returning number of bytes copied during transfer data operation. FrameOffset Starting offset in received frame where data transfer must start. The value of FrameOffset must be less than or equal to the value of BytesAvail from the corresponding ReceiveLookahead. TDBufDescr Virtual address of transfer descriptor describing where to store the frame data. Description: A protocol calls this synchronous routine from within its ReceiveLookahead handler before return, to ask the MAC to transfer data for a received frame to protocol storage. The protocol can specify any starting frame offset and byte count for the transfer, so long as these don't exceed the frame's length. If bit 15 of the MAC service flags is set, multiple TransferDatas may be called during a single ReceiveLookahead indication. If this bit is reset, only one TransferData per ReceiveLookahead indication is permitted. In the latter case subsequent calls within the same indication will return an error. For MACs with bit 15 of the MAC service flags reset, a protocol intending to call TransferData must do so only if it has decided to accept the incoming packet. Since the MAC driver may be shared by multiple protocols, a protocol's failure to follow this restriction in this case jeopardizes other coexisting protocol drivers from receiving these packets. When a protocol is bound to a MAC with bit 15 set, this restriction does not apply as a mandatory requirement. However, it is still recommended in such cases for performance reasons that a protocol call TransferData only if it has decided to accept the incoming packet. A protocol module must set the Lookahead size large enough to determine if the packet is intended for it by examining ony the Lookahead bytes presented by ReceiveLookahead. It is recommended that the multiple TransferData feature with bit 15 set be implemented in MAC drivers whenever it is reasonable to do so with the adapter hardware. IndicationComplete Purpose: Allow protocol to do post-processing on indications. PUSH WORD MACID ;Module ID of MAC PUSH WORD ProtDS ;DS of called protocol module CALL IndicationComplete Returns: 0x0000 SUCCESS 0x0007 INVALID_PARAMETER 0x00FF GENERAL_FAILURE Description: A MAC calls this entry point to enable a protocol to do post- processing after an indication. The MAC will always generate an IndicationComplete subsequent to an indication regardless of the return code of the indication. Although still in interrupt context and subject to the normal OS/2 guidelines for interrupt processing, the protocol is not under the severe time constraints of the indication. The MAC must minimize stack usage before calling this routine and, under DOS, must have swapped off of any special "interrupt" stack. This routine is always entered with interrupts enabled and with the network adapter interrupt dismissed from the interrupt controller. Therefore, it may be reentered at the completion of another indication. Also no one-to-one correspondence is guaranteed between indications and IndicationComplete. A MAC may generate one IndicationComplete for several indications. A protocol may enforce a one-to-one correspondence by leaving indications disabled until the return from IndicationComplete. If indications are explicitly disabled by a protocol on return from an indication, it is the protocol's responsibility to invoke IndicationOn as soon possible during IndicationComplete. MAC developers must avoid simply serializing each indication with IndicationComplete as this can negatively affect performance. The MAC must be designed to allow an indication to occur during IndicationComplete processing. Of course, if this occurs, another IndicationComplete call will be necessary. ReceiveChain Purpose: Indicate reception of a frame in MAC-managed buffers. PUSH WORD MACID ;Module ID of MAC PUSH WORD FrameSize ;Total size of frame (bytes) PUSH WORD ReqHandle ;Unique handle for this request PUSH LPBUF RxBufDescr ;Virtual address of receive descriptor PUSH LPBYTE Indicate ;Virtual address of indicate flag PUSH WORD ProtDS ;DS of called protocol module CALL ReceiveChain Returns: 0x0000 SUCCESS 0x0001 WAIT_FOR_RELEASE 0x0003 FRAME_NOT_RECOGNIZED 0x0004 FRAME_REJECTED 0x0005 FORWARD_FRAME 0x0006 OUT_OF_RESOURCE 0x0007 INVALID_PARAMETER 0x00FF GENERAL_FAILURE FrameSize Total size of received frame, in bytes. RxBufDescr Virtual address of receive descriptor describing the received frame. Indicate Virtual address of indication flag byte. This byte is set to 0xFF by the MAC prior to this call. If the protocol clears the byte to zero prior to returning then indications will be left disabled until IndicationOn is called from IndicationComplete. Description: A MAC calls this routine to indicate the reception of a frame in MAC-managed storage. Ownership of this storage is implicitly passed to the protocol when this call is made. At its option, the protocol may copy the data right away and indicate this via the return code (in which case ownership reverts to the MAC); or the protocol may queue the request and copy the frame later, in which case it retains ownership of the frame's storage until it calls ReceiveRelease. Since the protocol may queue data received in this manner, it is possible that the MAC may run low on available frame buffers. The MAC may elect to call ReceiveLookahead instead of ReceiveChain while it is low on frame buffers. This allows the MAC to retain control of its remaining buffers until the protocol releases the buffers it is holding. Note that for frames longer than 256 bytes, the MAC must guarantee that the first data block of the frame is at least 256 bytes long. Frames less than or equal to 256 bytes in length must be completely specified with a single data block. This allows the protocol to parse packet headers out of the first data block and greatly facilitates protocol processing efficiency. Like ReceiveLookahead, a protocol's processing within ReceiveChain is time critical. At some point after return from ReceiveChain the MAC will generate an IndicationComplete to allow post-processing of the indication. The MAC implicitly disables indications (IndicationOff) before calling ReceiveChain. The Indicate flag byte instructs the MAC on whether to reenable indications or leave then disable on the return. If the protocol chooses to leave indications disabled, it can enable them within IndicationComplete by calling IndicationOn. ReceiveRelease Purpose: Return frame storage to the MAC that owns it. PUSH WORD ReqHandle ;Unique handle from ReceiveChain PUSH WORD MACDS ;DS of called MAC module CALL ReceiveRelease Returns: 0x0000 SUCCESS 0x0007 INVALID_PARAMETER 0x0009 NOT_SUPPORTED 0x00FF GENERAL_FAILURE Description: A protocol uses this call after it has copied frame data provided by a ReceiveChain call. ReceiveRelease returns ownership of the frame data blocks to the MAC. IndicationOff Purpose: Disable MAC indications PUSH WORD MACDS ;DS of called MAC module CALL IndicationOff Returns: 0x0000 SUCCESS 0x0008 INVALID_FUNCTION 0x00FF GENERAL_FAILURE Description: A protocol may use this call to prevent the generation of ReceiveLookahead, ReceiveChain and Status indications from the MAC. This is similar in concept to disabling interrupts. When indications are off, a MAC must queue events that would cause it to generate indications to the protocol. A MAC implicitly disables indications just before calling the ReceiveLookahead, ReceiveChain or Status indication entry point of a protocol. The only legal use of IndicationOff is to bracket a call or calls to the MAC. For example, the following sequence is valid: IndicationOff TransmitChain IndicationOn In this situation the protocol must not block while indications are off and must call IndicationOn as soon as possible. The protocol must ensure that all calls to IndicationOff are paired up with a corresponding call to IndicationOn. If the protocol issues an IndicationOff call from a timer tick handler, or from a ReceiveLookahead, ReceiveChain or Status indication handler it must issue the IndicationOn call before returning. Note that IndicationComplete may still occur even though indications are disabled. Disabling indications has no effect on a MAC's ability to call IndicationComplete. This function always returns with interrupts disabled. It is the responsibility of the caller to re-enable them. IndicationOn Purpose: Enable MAC indications Called from protocol to MAC. PUSH WORD MACDS ;DS of called MAC module CALL IndicationOn Returns: 0x0000 SUCCESS 0x0008 INVALID_FUNCTION 0x00FF GENERAL_FAILURE Description: A protocol must use this call to re-enable indications after having disabled them. Note that a MAC may optionally defer the actual re-enabling of indications. It is possible that IndicationOff and IndicationOn pairs will nest. Therefore the MAC must maintain a reference count to enable it to determine when to actually re-enable indications. The protocol must not assume that a call to IndicationOn will immediately enable indications. IndicationOn may be called from an IndicationComplete handler after leaving indications disabled on return from an indication handler. IndicationOn may also be used, paired with IndicationOff, to bracket a call or calls to the MAC. This function always returns with interrupts disabled. It is the responsibility of the caller to re-enable them. No indications will be generated until after the call has returned. General Requests General requests are commands from a protocol to a MAC directing it to do adapter management operations like setting the station address, running diagnostics, and changing operating parameters or modes. A MAC may choose to implement any of the Request functions synchronously or asynchronously. A MAC returns the REQUEST_QUEUED return code to inform the protocol that a given request will be processed asynchronously. When this is the case, the MAC will call back to the protocol's RequestConfirm entry point to indicate when processing of the request is complete. If a request handle of zero is used then the RequestConfirm call is suppressed. It is the caller's responsibility to make certain that any data referenced by the request remains valid until the request is guaranteed to have completed. If a protocol makes a general MAC request when executing its InitiateBind startup function and the MAC returns REQUEST_QUEUED, the protocol must wait for the corresponding RequestConfirm to be returned before exiting from the InitiateBind function. Any other return code from a general request implies that no RequestConfirm will occur. All general requests have the following common calling convention: PUSH WORD ProtID ;Module ID of Protocol or 0 PUSH WORD ReqHandle ;Unique handle for this request or 0 PUSH WORD Param1 ;Request dependent word parameter or 0 PUSH DWORD Param2 ;Request dependent dword parameter or 0 PUSH WORD Opcode ;Opcode of request PUSH WORD MACDS ;DS of called MAC module Call Request InitiateDiagnostics Purpose: Start runtime diagnostics. PUSH WORD ProtID ; Module ID of Protocol PUSH WORD ReqHandle ; Unique handle for this request or 0 PUSH WORD 0 ; Pad parameter - must be 0 PUSH DWORD 0 ; Pad parameter - must be 0 PUSH WORD 1 ; Initiate Diagnostics Request PUSH WORD MACDS ; DS of called MAC module Call Request Returns: 0x0000 SUCCESS 0x0002 REQUEST_QUEUED 0x0006 OUT_OF_RESOURCE 0x0007 INVALID_PARAMETER 0x0008 INVALID_FUNCTION 0x0009 NOT_SUPPORTED 0x000A HARDWARE_ERROR 0x00FF GENERAL_FAILURE Description: Causes a MAC to run hardware diagnostics and update its status information in the MAC-specific status section of the characteristics table. A MAC must return an error if it does not support run time diagnostics. While the diagnostics are in progress, the MAC must set the diagnostics in progress bit (bit 5) in the MAC status field in the MAC service-specific status table. If HARDWARE_ERROR is returned, the protocol may examine the various fields in the service-specific status table for an indication as to the cause of the problem. ReadErrorLog Purpose: Return error log. PUSH WORD ProtID ; Module ID of Protocol PUSH WORD ReqHandle ; Unique handle for this request or 0 PUSH WORD LogLen ; Length of log buffer PUSH LPBUF LogAddr ; Buffer for returning log PUSH WORD 2 ; Read Error Log Request PUSH WORD MACDS ; DS of called MAC module Call Request Returns: 0x0000 SUCCESS 0x0002 REQUEST_QUEUED 0x0006 OUT_OF_RESOURCE 0x0007 INVALID_PARAMETER 0x0008 INVALID_FUNCTION 0x0009 NOT_SUPPORTED 0x00FF GENERAL_FAILURE Description: Causes a read error log to be issued to adapter. This command is implemented on the IBM token ring adapter and possibly other adapters. The format of the information returned is adapter specific and not specified here. SetStationAddress Purpose: Set the network address of the station. PUSH WORD ProtID ; Module ID of Protocol PUSH WORD ReqHandle ; Unique handle for this request or 0 PUSH WORD 0 ; Pad parameter - must be 0 PUSH LPBUF AdaptAddr ; Buffer containing the adapter address PUSH WORD 3 ; SetStationAddress Request PUSH WORD MACDS ; DS of called MAC module Call Request Returns: 0x0000 SUCCESS 0x0002 REQUEST_QUEUED 0x0006 OUT_OF_RESOURCE 0x0007 INVALID_PARAMETER 0x0008 INVALID_FUNCTION 0x0009 NOT_SUPPORTED 0x00FF GENERAL_FAILURE Description: There is only a single station address. Each time it replaces the current station address in the MAC service-specific characteristics table and will reconfigure the hardware to receive on that address if required. The station will be initially configured with the address specified in the permanent station address field of the MAC service-specific characteristics table (which this call does not modify). The adapter address buffer contains only the bytes of the address to be set. The length of the address must be equal to the length specified in the MAC service characteristics table. If the hardware does not support a mechanism to modify its station address then the current station address buffer is not updated and this function returns INVALID_FUNCTION. In this case the MAC continues to use the permanent station address to recognize incoming directed packets. If a MAC does not support the OpenAdapter and CloseAdapter commands (bit 11 of the MAC service flags is reset), then the SetStationAddress command can be issued by the protocol at any time. However, if the MAC supports the Open Adapter and CloseAdapter commands (bit 11 of the MAC service flags is set), then this command is valid only either during system initialization time or while the MAC is in a closed state. The protocol driver must issue an Open Adapter call after issuing the SetStationAddress call for the SetStationAddress command to take effect. OpenAdapter Purpose: Issue open request to network adapter. PUSH WORD ProtID ; Module ID of Protocol PUSH WORD ReqHandle ; Unique handle for this request or 0 PUSH WORD OpenOptions ; Adapter specific open options PUSH DWORD ExtendedRet ; Optional pointer to a DWORD extended return code (vendor-specific or warning level) PUSH WORD 4 ; Open Adapter Request PUSH WORD MACDS ; DS of called MAC module Call Request Returns: 0x0000 SUCCESS 0x0002 REQUEST_QUEUED 0x0006 OUT_OF_RESOURCE 0x0007 INVALID_PARAMETER 0x0008 INVALID_FUNCTION 0x0009 NOT_SUPPORTED 0x0024 HARDWARE_FAILURE 0x002A NETWORK_MAY_NOT_BE_CONNECTED 0x00FF GENERAL_FAILURE Where: Optional vendor-specific information can be returned through the ExtendedRet pointer. A caller supporting this would push a pointer to a DWORD. The DWORD would have been initialized to 0xFFFFFFFF (unsupported). If there is any extended return information this value would be changed. A caller not supporting this would simply push a NULL (0) pointer. The OpenAdapter routine which supports this would verify the ExtendedRet pointer is not NULL (0) and then write the information. The OpenAdapter routine which does not support this would simply ignore the pointer. The purpose of ExtendedRet is to provide warning messages on a SUCCESS return without requiring additional testing for those callers not supporting warnings, to provide additional information on GENERAL_FAILURE and HARDWARE_FAILURE, and to pass vendor-specific codes on any return to provide for active functional experimentation and evolution without inconveniencing other vendor's components. Description: The purpose of the OpenAdapter function is to activate an adapter's network connection. This may involve making an electrical connection for some adapters like token ring adapters. This also implies that a considerable delay may occur between submittal of this request and its confirmation. If the MAC indicates that OpenAdapter is supported (by setting bit 11 of the service flags in the MAC service-specific characteristics table), then the protocol driver must ensure the adapter is open during bind-time processing. Since OpenAdapter can only be called when the adapter is closed, even in a VECTOR configuration, the protocol must first check if the adapter is already open by examining bit 4 of the MAC status in the MAC service-specific status table. While an adapter is closed the following functions are guaranteed to operate: SetLookahead, SetPacketFilter, SetStationAddress, Interrupt, Indicationoff, IndicationOn. Since this function is adapter specific it is expected that any necessary parameters are either known a priori by the MAC or can be recovered from the PROTOCOL.INI file. The format of the information is highly adapter specific and left up to the implementer to define. The OpenOptions parameter is adapter specific. For IBM TokenRing and compatible adapters, these are defined in the IBM Token Ring Technical Reference Manual. CloseAdapter Purpose: Issue close request to network adapter. PUSH WORD ProtID ; Module ID of Protocol PUSH WORD ReqHandle ; Unique handle for this request or 0 PUSH WORD 0 ; Pad parameter - must be 0 PUSH DWORD 0 ; Pad parameter - must be 0 PUSH WORD 5 ; Close Adapter Request PUSH WORD MACDS ; DS of called MAC module Call Request Returns: 0x0000 SUCCESS 0x0002 REQUEST_QUEUED 0x0006 OUT_OF_RESOURCE 0x0007 INVALID_PARAMETER 0x0008 INVALID_FUNCTION 0x0009 NOT_SUPPORTED 0x00FF GENERAL_FAILURE Description: This function closes an adapter. This causes it to decouple itself from a network so that packets cannot be sent or received. CloseAdapter resets the functional or multicast addresses currently set. Since this function is adapter specific it is expected that any necessary parameters are either already known by the MAC or can be recovered from the PROTOCOL.INI file. The format of the information is highly adapter specific and left up to the implementer to define. ResetMAC Purpose: Reset the MAC software and adapter hardware. PUSH WORD ProtID ; Module ID of Protocol PUSH WORD ReqHandle ; Unique handle for this request or 0 PUSH WORD 0 ; Pad parameter - must be 0 PUSH DWORD 0 ; Pad parameter - must be 0 PUSH WORD 6 ; Reset MAC Request PUSH WORD MACDS ; DS of called MAC module Call Request Returns: 0x0000 SUCCESS 0x0006 OUT_OF_RESOURCE 0x0007 INVALID_PARAMETER 0x0008 INVALID_FUNCTION 0x0009 NOT_SUPPORTED 0x0024 HARDWARE FAILURE 0x002A NETWORK_MAY_NOT_BE_CONNECTED 0x00FF GENERAL_FAILURE Description: The function causes the MAC to issue a hardware reset to the network adapter. The MAC may discard without confirmation any pending requests and abort operations in progress. For compatibility with some current protocols which do not properly handle resets, it is suggested the MAC complete pending requests, returning INVALID_FUNCTION on all confirmations which result. The MAC must preserve the current station address, LOOKAHEAD length, packet filter, multicast address list, functional address and indication on/off state. For MAC's that support the OpenAdapter function, the Reset MAC command leaves the adapter in the opened state if it was opened prior to the reset. The adapter open parameters that were in effect prior to the reset must be the same ones in effect after the reset. When the reset is initiated, the MAC must generate a StartReset status indication back to the protocol. For some MAC's a considerable delay can elapse between the start of the reset and its completion. All MAC's must subsequently issue an EndReset indication when the reset is complete. During the time between the StartReset indication and the corresponding EndReset indication, the MAC must return INVALID_FUNCTION for any request it receives while a reset is in progress. The EndReset indication notifies the protocol that the MAC can handle new requests. As always, an IndicationComplete follows these indications. MACSs written to V1.0.1. of this spec will not issue the End Reset. They must issue the IndicationCompleteto signal the end of the reset. Note that the completion (i.e. the return from this command or the request confirm) of the Reset MAC request itself does not signal the start or end of the reset. There can be no guarantee that this function will succeed, though the NDIS MAC developer must make every attempt. An error return from this call can be considered fatal. If the reset fails, the adapter may no longer be in the same state. For example, if the adapter was open before a failed ResetMAC, it may now be closed. SetPacketFilter Purpose: Select received packet general filtering parameters. PUSH WORD ProtID ; Module ID of Protocol PUSH WORD ReqHandle ; Unique handle for this request or 0 PUSH WORD FilterMask ; Bit mask for packet filter PUSH DWORD 0 ; Pad parameter - must be 0 PUSH WORD 7 ; Set Packet Filter Request PUSH WORD MACDS ; DS of called MAC module Call Request FilterMask bit 0 directed and multicast or group and functional 1 broadcast packets 2 any packet on LAN (promiscuous) 3 any source routing packet on LAN 4-15 Reserved, must be zero Returns: 0x0000 SUCCESS 0x0002 REQUEST_QUEUED 0x0006 OUT_OF_RESOURCE 0x0007 INVALID_PARAMETER 0x0008 INVALID_FUNCTION 0x00FF GENERAL_FAILURE Description: This command tells the MAC which kinds of received packets must generate indications to the protocol invoking this command. A FilterMask of 0 indicates that the MAC must not indicate received packets to that protocol. If a FilterMask bit is set, then this indicates that the MAC must indicate that type of packet to the protocol. Except for a 0 FilterMask, a filter bit of 0 does not require the MAC to suppress indications for that type of packet. For example the FilterMask used by the MAC may or may not correspond to the capabilities of the hardware adapter. For example a MAC may be designed to receive multicast frames by promiscuously receiving all frames and discarding those that do not match the filter. It is optional for the MAC to support such software filtering. If the MAC can suppress such indications, it is strongly recommended that it do so. However, if the MAC does not suppress such indications, then the protocol must be prepared to receive these and discard the incoming packet if necessary. If this request returns SUCCESS, then the hardware is enabled to receive the types of packets requested and will generate Indications to the protocol for those types of packets. If the MAC does not support the receiving of packets of the type specified, then it will return GENERAL_FAILURE. In this case the FilterMask is left in its previous state. AddMulticastAddress Purpose: Allow adapter to respond to a multicast address. PUSH WORD ProtID ; Module ID of Protocol PUSH WORD ReqHandle ; Unique handle for this request or 0 PUSH WORD 0 ; Pad parameter - must be 0 PUSH LPBUF MultiAddr ; Buffer containing multicast address PUSH WORD 8 ; Add Multicast Address Request PUSH WORD MACDS ; DS of called MAC module Call Request Returns: 0x0000 SUCCESS 0x0002 REQUEST_QUEUED 0x0006 OUT_OF_RESOURCE 0x0007 INVALID_PARAMETER 0x0008 INVALID_FUNCTION 0x0009 NOT_SUPPORTED 0x00FF GENERAL_FAILURE Description: This function allows the addition of multicast addresses. The term multicast address also implies 802.5 group addresses. This function allows the addition of only one address at a time but can be repeated to add more multicasts. It is the MAC's responsibility to return an error if too many multicast addresses have been added (OUT_OF_RESOURCE or INVALID_FUNCTION) or if an address of the wrong type has been added (INVALID_PARAMETER). Multicast addresses are never over written and will return an error (INVALID_PARAMETER) if they already exist no matter what their type. They must be explicitly deleted. The multicast address buffer contains only the bytes of the multicast address to be added. The length of the multicast address must be equal to the length specified in the MAC service characteristics table. DeleteMulticastAddress Purpose: Forbid adapter to respond to a multicast address. PUSH WORD ProtID ; Module ID of Protocol PUSH WORD ReqHandle ; Unique handle for this request or 0 PUSH WORD 0 ; Pad parameter - must be 0 PUSH LPBUF MultiAddr ; Buffer containing multicast address PUSH WORD 9 ; Delete Multicast Address Request PUSH WORD MACDS ; DS of called MAC module Call Request Returns: 0x0000 SUCCESS 0x0002 REQUEST_QUEUED 0x0006 OUT_OF_RESOURCE 0x0007 INVALID_PARAMETER 0x0008 INVALID_FUNCTION 0x0009 NOT_SUPPORTED 0x00FF GENERAL_FAILURE Description: This function removes a previously added multicast address. The term multicast address also implies 802.5 group addresses. INVALID_PARAMETER is returned if the address was not in the table. The multicast address buffer has the same format as in the AddMulticastAddress command. UpdateStatistics Purpose: Cause MAC statistics to be updated. PUSH WORD ProtID ; Module ID of Protocol PUSH WORD ReqHandle ; Unique handle for this request or 0 PUSH WORD 0 ; Pad parameter - must be 0 PUSH DWORD 0 ; Pad parameter - must be 0 PUSH WORD 10 ; Update Statistics request PUSH WORD MACDS ; DS of called MAC module Call Request Returns: 0x0000 SUCCESS 0x0002 REQUEST_QUEUED 0x0006 OUT_OF_RESOURCE 0x0007 INVALID_PARAMETER 0x0008 INVALID_FUNCTION 0x00FF GENERAL_FAILURE Description: Causes the MAC to atomically update the statistics in its characteristics table. The requester can then read that table when this operation is complete. Those statistics which are not always current will remain the same until the next UpdateStatistics call is performed. If all of the statistics in the table are always current this function must return SUCCESS. ClearStatistics Purpose: Cause MAC statistics to be cleared. PUSH WORD ProtID ; Module ID of Protocol PUSH WORD ReqHandle ; Unique handle for this request or 0 PUSH WORD 0 ; Pad parameter - must be 0 PUSH DWORD 0 ; Pad parameter - must be 0 PUSH WORD 11 ; Clear Statistics request PUSH WORD MACDS ; DS of called MAC module Call Request Returns: 0x0000 SUCCESS 0x0002 REQUEST_QUEUED 0x0006 OUT_OF_RESOURCE 0x0007 INVALID_PARAMETER 0x0008 INVALID_FUNCTION 0x00FF GENERAL_FAILURE Description: Causes the MAC to reset its statistics counters. This implies that all statistics must be reset to zero in an atomic operation. InterruptRequest Purpose: Request asynchronous indication. PUSH WORD ProtID ; Module ID of Protocol PUSH WORD 0 ; Pad parameter - must be 0 PUSH WORD 0 ; Pad parameter - must be 0 PUSH DWORD 0 ; Pad parameter - must be 0 PUSH WORD 12 ; InterruptRequest PUSH WORD MACDS ; DS of called MAC module Call Request Returns: 0x0000 SUCCESS 0x0006 OUT_OF_RESOURCE 0x0008 INVALID_FUNCTION 0x0009 NOT_SUPPORTED 0x00FF GENERAL_FAILURE Description: This function requests the MAC to generate an asynchronous Interrupt Status indication back to the protocol. The protocol may control the generation of this Interrupt Status indication by disabling and later enabling indications. The MAC may at its discretion suppress the generation of this indication if there is another indication pending which may be issued in place of the Interrupt status indication. This request is intended to be used for MAC's which can generate a hardware interrupt on demand. This function must be implemented if at all possible. Interrupt request will substantially improve the performance of some protocols (particularly DLC). SetFunctionalAddress Purpose: Cause adapter to change its functional address. PUSH WORD ProtID ; Module ID of Protocol PUSH WORD ReqHandle ; Unique handle for this request or 0 PUSH WORD 0 ; Pad parameter - must be 0 PUSH LPBUF FunctAddr ; Buffer containing functional address PUSH WORD 13 ; Set Functional Address Request PUSH WORD MACDS ; DS of called MAC module Call Request Returns: 0x0000 SUCCESS 0x0002 REQUEST_QUEUED 0x0006 OUT_OF_RESOURCE 0x0007 INVALID_PARAMETER 0x0008 INVALID_FUNCTION 0x0009 NOT_SUPPORTED 0x00FF GENERAL_FAILURE Description: This sets the IEEE802.5 functional address to the passed functional address. The adapter will use the functional address to discern packets intended for it. For more information on functional addresses see the IEEE 802.5 specification. The functional address buffer contains only the bytes of the new functional address bit pattern. It represents the logical OR of all functional addresses to be registered with the adapter. The length of the functional address buffer is 4 bytes. Multiple protocols can set or reset their functional address bit if required by each protocol by first reading the current functional address DWORD bit pattern from the MAC service characteristics table, then ORing in or ANDing out the required functional bit and passing the new functional address pattern in this command. SetLookahead Purpose: Set length of lookahead information for ReceiveLookahead. PUSH WORD ProtID ; Module ID of Protocol PUSH WORD ReqHandle ; Unique handle for this request or 0 PUSH WORD Length ; Minimum length of lookahead info PUSH DWORD 0 ; Pad parameter - must be 0 PUSH WORD 14 ; Set Lookahead Request PUSH WORD MACDS ; DS of called MAC module Call Request Returns: 0x0000 SUCCESS 0x0002 REQUEST_QUEUED 0x0007 INVALID_PARAMETER 0x00FF GENERAL_FAILURE Description: This request sets the minimum length in bytes of lookahead information to be returned in a Receive Lookahead indication. Until SetLookahead is initially called, a value of 64 bytes is assumed for the lookahead length. When first called, SetLookahead sets the lookahead length value equal to the Length parameter of the request. After the first SetLookahead request, the lookahead length is changed only if the value of the Length parameter is larger than the current lookahead length. If the length parameter value is smaller, the current Lookahead length remains unchanged and SUCCESS is returned. SetLookahead may be called at any time and the lookahead length is preserved during a reset. The maximum value for the lookahead length is 256 bytes. MAC's which never call Receive Lookahead or always return lookahead information of length greater than or equal to 256 bytes may return SUCCESS without any internal action. MAC's must support 256 bytes of lookahead data if requested. General Request Confirmation Purpose: Confirm completion of a previous General Request. PUSH WORD ProtID ; Module ID of Protocol PUSH WORD MACID ; Module ID of MAC PUSH WORD ReqHandle ; Unique handle of original request PUSH WORD Status ; Final status of original request PUSH WORD Request ; Original Request opcode PUSH WORD ProtDS ; DS of called Protocol module Call RequestConfirm Returns: 0x0000 SUCCESS 0x0006 OUT_OF_RESOURCE 0x0007 INVALID_PARAMETER 0X0024 HARDWARE_FAILURE 0x00FF GENERAL_FAILURE Description: Notify a protocol that an asynchronous MAC control Request has completed after previous Request had returned a REQUEST_QUEUED. It is possible that a RequestConfirm can be returned to the protocol before the protocol's corresponding Request function has completed. The ProtID parameter must be the value passed by the protocol on the previous general request to identify the requestor. If a protocol had made a general MAC request when executing its InitiateBind startup function and the MAC returned REQUEST_QUEUED, the protocol must wait for the corresponding RequestConfirm to be returned before exiting from the InitiateBind function. Status Indication Status indications are spontaneous calls from a MAC to a protocol, typically at interrupt time. They inform the protocol of changes in MAC status. All status indications have the following common calling convention: PUSH WORD MACID ; Module ID of MAC PUSH WORD Param1 ; Opcode dependent word parameter or 0 PUSH LPBYTE Indicate ; Virtual address of indicate flag PUSH WORD Opcode ; Opcode of status indication PUSH WORD ProtDS ; DS of called Protocol module Call Status Indicate is the virtual address of the indication flag byte. This byte is set to 0xFF by the MAC prior to this call. If the protocol clears the byte to zero prior to returning then indications will be left disabled until IndicationOn is called from IndicationComplete. RingStatus Purpose: Return a change in ring status. PUSH WORD MACID ; Module ID of MAC PUSH WORD Status ; New Ring Status PUSH LPBYTE Indicate ; Virtual address of indicate flag PUSH WORD 1 ; Ring Status Indication PUSH WORD ProtDS ; DS of called protocol module Call Indication Returns: 0x0000 SUCCESS Description: Called by 802.5-style MAC drivers to indicate a change in ring status. The status codes for 802.5-style drivers are encoded as a 16-bit mask, where the bits in the mask are defined as follows: Bit