NT4/private/ntos/ndis/elnk3/elnk3hrd.h
2020-09-30 17:12:29 +02:00

550 lines
15 KiB
C

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
elnk3hrd.h
Abstract:
Ndis 3.0 MAC driver for the 3Com Etherlink III
Author:
Brian Lieuallen BrianLie 08/21/92
Environment:
Kernel Mode Operating Systems : NT
Revision History:
Portions borrowed from ELNK3 driver by
Earle R. Horton (EarleH)
--*/
#define ELNK3_ETHERNET_HEADER_SIZE 14
#define ELNK3_MAX_FRAME_SIZE 1514
#define ELNK3_MAX_LOOKAHEAD_SIZE 1500
typedef struct _ETHERNET_HEADER {
UCHAR Destination[6];
UCHAR Source[6];
UCHAR EthLength[2];
} ETHERNET_HEADER, *PETHERNET_HEADER;
typedef struct _NIC_RCV_HEADER {
ETHERNET_HEADER EthHeader;
UCHAR LookAheadData[1500];
} NIC_RCV_HEADER, *PNIC_RCV_HEADER;
//
// EhterTypes
//
#define XNS_FRAME_TYPE 0x0600
#define IP_FRAME_TYPE 0x0800
#define IPX_FRAME_TYPE 0x8137
typedef struct _XNSHDR {
UCHAR Ether[ELNK3_ETHERNET_HEADER_SIZE];
USHORT Checksum;
UCHAR Size[2];
} XNSHDR, PXNSHDR;
typedef struct _IPHRD {
UCHAR Ether[ELNK3_ETHERNET_HEADER_SIZE];
USHORT Type;
UCHAR Size[2];
} IPHDR, PIPHDR;
typedef struct _IPXHDR {
UCHAR Ether[ELNK3_ETHERNET_HEADER_SIZE];
USHORT Checksum;
UCHAR Size[2];
} IPXHDR, PIPXHDR;
typedef struct _BUFFDESC {
ULONG CardOffset;
PNDIS_PACKET pPacket;
} BUFFDESC, *PBUFFDESC;
typedef enum _ELNK3_ADAPTER_TYPE {
ELNK3_3C509,
ELNK3_3C579,
ELNK3_3C529,
ELNK3_3C589
} ELNK3_ADAPTER_TYPE, PELNK3_ADAPTER_TYPE;
#define ELNK3_3C529_TP_MCA_ID 0x627c
#define ELNK3_3C529_BNC_MCA_ID 0x627d
#define ELNK3_3C529_COMBO_MCA_ID 0x61db
#define ELNK3_3C529_TPCOAX_MCA_ID 0x62f6
#define ELNK3_3C529_TPONLY_MCA_ID 0x62f7
#define ELNK3_EISA_ID 0x90506d50
#define ELNK3_3C579_EISA_ID 0x92506d50
#define ELNK3_3C509_EISA_ID 0x90506d50
/* :ts=4 this file uses 4 space tab stops */
/*
Hardware equates for the EtherLink III network adapter.
Adapted from
"3C509 and 3C509-TP Adapters Technical Reference Guide"
Manual Part No. 8369-00
3COM Corporation
*/
/*
When the adapter is in the ID_CMD state, the following writes to
the ID port are interpreted as commands.
*/
#define IDCMD_WAIT 0x00 /* Go to ID_WAIT state, actually 0 to 0x7f */
#define IDCMD_READ_PROM 0x80 /* Read EEPROM word n, n is last six bits */
/* of command */
#define IDCMD_RESET 0xC0 /* Global reset, same as power on reset */
#define IDCMD_SET_TAG 0xD0 /* Set Adapter tag to value in last 3 bits */
#define IDCMD_TEST_TAG 0xD8 /* Test Adapter tag by value in last 3 bits */
#define MAXTAG 7
#define IDCMD_ACTIVATE 0xE0 /* Activate adapter, writing last 5 bits */
/* into Address Configuration register */
#define IDCMD_ACTIVATE_FF 0xFF /* Activate adapter using preconfigured */
/* I/O base address */
/*
Default configuration values for the EtherLink III adapter.
*/
#define DEFAULT_ID_PORT 0x00000110 /* A port (maybe) not being used by */
/* anything else in an ISA machine */
/*
Card EEPROM configuration, as shipped.
*/
#define DEFAULT_IO_PORT (PVOID)0x300
#define DEFAULT_IRQ 10
#define DEFAULT_TRANSCEIVER TRANSCEIVER_BNC /* For the 3C509-TP, this will */
/* be TRANSCEIVER_TP */
// AdaptP->MulticastListMax
//
// the maximum number of different multicast addresses that
// may be specified to this adapter (the list is global for
// all protocols).
#define DEFAULT_MULTICASTLISTMAX 16
/*
EEPROM data structure.
*/
#define EEPROM_NODE_ADDRESS_0 0
#define EEPROM_NODE_ADDRESS_1 1
#define EEPROM_NODE_ADDRESS_2 2
#define EEPROM_PRODUCT_ID 3
#define EEPROM_MANUFACTURING_DATE 4
#define EEPROM_MANUFACTURING_DATA1 5
#define EEPROM_MANUFACTURING_DATA2 6
#define EEPROM_MANUFACTURER_CODE 7
#define EEPROM_ADDRESS_CONFIGURATION 8
#define EEPROM_RESOURCE_CONFIGURATION 9
#define EEPROM_OEM_NODE_0 10
#define EEPROM_OEM_NODE_1 11
#define EEPROM_OEM_NODE_2 12
#define EEPROM_SOFTWARE_INFO 13
#define EEPROM_RESERVED 14
#define EEPROM_CHECKSUM 15
#define EEPROM_NETWORK_MANAGEMENT_DATA_0 16
//
// eeprom software info bits
//
#define LINK_BEAT_DISABLED (1<<14)
/*
Address configuration register.
*/
typedef union ELNK3_Address_Configuration_Register{
struct{
USHORT eacf_iobase : 5;
USHORT eacf_reserved : 3;
USHORT eacf_ROMbase : 4;
USHORT eacf_ROMsize : 2;
USHORT eacf_XCVR : 2;
};
USHORT eacf_contents;
}ELNK3_Address_Configuration_Register, *PELNK3_Address_Configuration_Register;
/*
EtherLink III configuration control register.
*/
#define CCR_ENABLE_BIT 0
#define CCR_RESET_BIT 2
#define CCR_ENABLE ( 1 << CCR_ENABLE_BIT )
#define CCR_RESET ( 1 << CCR_RESET_BIT )
/*
Transceiver configuration as stored in Address Configuration Register.
*/
#define TRANSCEIVER_TP 0 /* Twisted pair transceiver enabled. */
#define TRANSCEIVER_EXTERNAL 1 /* AUI port enabled, using ext. trans. */
#define TRANSCEIVER_RESERVED 2 /* reserved - undefined */
#define TRANSCEIVER_BNC 3 /* BNC transceiver enabled */
#define TRANSCEIVER_UNDEFINED TRANSCEIVER_RESERVED
/* Handy dandy undefined transceiver value */
/*
Conversion from eacf_iobase to I/O port used.
*/
#define IOBASE_EISA 0x31 /* EISA mode slot-specific I/O address */
typedef union EISA_IO_Address {
struct{
USHORT eia_port : 12;
USHORT eia_slot : 4;
};
USHORT eia_contents;
}EISA_IO_Address, *PEISA_IO_Address;
#define EISA_Window_0_Address 0xC80 /* Window zero is always mapped here */
/* on an EISA machine configured */
/* adapter */
/*
IOBaseAddress for an EtherLink III configured for EISA operation and installed
in an EISA slot is the slotnumber times 1000h.
*/
#define EISA_SlotNumber_To_IOBase(x) ((x) * 0x1000)
#define EACF_IOBASE_TO_ISA_IOBASE(x) ( ( (x) << 4 ) + 0x200 )
#define ISA_IOBASE_TO_EACF_IOBASE(x) ( ( (x) - 0x200 ) >> 4 )
/*
Elnk III resource configuration register.
*/
typedef union ELNK3_Resource_Configuration_Register{
struct{
USHORT ercf_reserved : 8;
USHORT ercf_reserved_F : 4;
USHORT ercf_IRQ : 4;
};
USHORT ercf_contents;
}ELNK3_Resource_Configuration_Register, *PELNK3_Resource_Configuration_Register;
/*
Format of command word written to ELNK III command register.
*/
typedef union ELNK3_Command{
struct{
USHORT ec_arg : 11;
USHORT ec_command : 5;
};
USHORT ec_contents;
}ELNK3_Command,*PELNK3_Command;
#define EC_GLOBAL_RESET 0
#define EC_SELECT_WINDOW 1
#define EC_START_COAX_XCVR 2
#define EC_RX_DISABLE 3
#define EC_RX_ENABLE 4
#define EC_RX_RESET 5
#define EC_RX_DISCARD_TOP_PACKET 8
#define EC_TX_ENABLE 9
#define EC_TX_DISABLE 10
#define EC_TX_RESET 11
#define EC_REQUEST_INTERRUPT 12
#define EC_INT_LATCH 0x01
#define EC_INT_ADAPTER_FAILURE 0x02
#define EC_INT_TX_COMPLETE 0x04
#define EC_INT_TX_AVAILABLE 0x08
#define EC_INT_RX_COMPLETE 0x10
#define EC_INT_RX_EARLY 0x20
#define EC_INT_INTERRUPT_REQUESTED 0x40
#define EC_INT_UPDATE_STATISTICS 0x80
#define EC_ACKNOWLEDGE_INTERRUPT 13
#define EC_SET_INTERRUPT_MASK 14
#define EC_SET_READ_ZERO_MASK 15
#define EC_SET_RX_EARLY 17
#define EC_SET_TX_AVAILIBLE 18
#define EC_SET_TX_START 19
#define EC_SET_RX_FILTER 16
#define EC_FILTER_ADDRESS 1
#define EC_FILTER_GROUP 2
#define EC_FILTER_BROADCAST 4
#define EC_FILTER_PROMISCUOUS 8
//
// Window Numbers
//
#define WNO_SETUP 0 // setup/configuration
#define WNO_OPERATING 1 // operating set
#define WNO_STATIONADDRESS 2 // station address setup/read
#define WNO_FIFO 3 // FIFO management
#define WNO_DIAGNOSTICS 4 // diagnostics
#define WNO_READABLE 5 // registers set by commands
#define WNO_STATISTICS 6 // statistics
//
// Port offsets, Window 1
//
#define PORT_CmdStatus 0x0E // command/status
#define PORT_TxFree 0x0C // free transmit bytes
#define PORT_TxStatus 0x0B // transmit status (byte)
#define PORT_Timer 0x0A // latency timer (byte)
#define PORT_RxStatus 0x08 // receive status
#define PORT_RxFIFO 0x00 // RxFIFO read
#define PORT_TxFIFO 0x00 // TxFIFO write
//
// Port offsets, Window 0
//
#define PORT_EEData 0x0C // EEProm data register
#define PORT_EECmd 0x0A // EEProm command register
#define PORT_CfgResource 0x08 // resource configuration
#define PORT_CfgAddress 0x06 // address configuration
#define PORT_CfgControl 0x04 // configuration control
#define PORT_ProductID 0x02 // product id (EISA)
#define PORT_Manufacturer 0x00 // Manufacturer code (EISA)
//
// Port offsets, Window 2
//
#define PORT_SA0_1 0x00 // station address bytes 0,1
#define PORT_SA2_3 0x02 // station address bytes 2,3
#define PORT_SA4_5 0x04 // station address bytes 4,5
//
// port offsets, window 3
//
#define PORT_FREE_RX_BYTES 0x0a
//
//
// Port Offsets window 4
//
#define PORT_FIFO_DIAG 0x04
#define RX_UNDERRUN 0x2000
#define TX_OVERRUN 0x0400
#define PORT_MEDIA_TYPE 0x0a
#define MEDIA_LINK_BEAT 0x0080
#define MEDIA_JABBER 0x0040
#define MEDIA_SQE 0x0008
#define PORT_NET_DIAG 0x06
//
// board identification codes
//
#define EISA_MANUFACTURER_ID 0x6D50 // EISA manufacturer code
#define ISAID_BNC 0x9050 // Product ID for ISA TP board
#define ISAID_TP 0x9051 // Product ID for ISA coax board
#define EISAID 0x9052 // Product ID for EISA board
#define PCMCIAID 0x9058 // Product ID for PCMCIA board (3C589)
//...so far the list is 5090=ISA 3C509-TP (TP/AUI), 5091h=ISA 3C509 (BNC/AUI),
// 5092h=EISA 3C579-TP (TP/AUI) and 5092h=EISA 3C579 (BNC/AUI). other
// bottom nibbles will likely be assigned to TP-only/combo/whatever
// else marketting thinks up...
#define PRODUCT_ID_MASK 0xF0FF // Mask off revision nibble
#define MCAID_BNC 0x627C // MCA Adapter ID: BNC/AUI
#define MCAID_TP 0x627D // MCA Adapter ID: TP/AUI
#define MCAID_COMBO 0x61DB // MCA Adapter ID: Combo (future)
#define MCAID_TPCOAX 0x62F6 // MCA Adapter ID: TP/COAX (future)
#define MCAID_TPONLY 0x62F7 // MCA Adapter ID: TP only (future)
/*
Note: This is referred to as POS2 in 3COM's MCA Technical Reference Addendum
for the EtherLink III.
*/
#define POS1_CDEN 1 // Card enable bit in POS2 register
/*
Note: This is referred to as POS4 in 3COM's MCA Technical Reference Addendum
for the EtherLink III.
*/
#define POS3_TO_IOBASE(x) ((((x) << 8) & 0xFC00) | 0x0200)
//
// EEProm access
//
#define EE_COMMAND_EW_ENABLE 0x30
#define EE_COMMAND_ERASE 0xc0
#define EE_COMMAND_WRITE 0x40
#define EE_COMMAND_READ 0x80
#define EE_BUSY 0x8000 // EEProm busy bit in EECmd
#define EE_TCOM_NODE_ADDR_WORD0 0x00
#define EE_TCOM_NODE_ADDR_WORD1 0x1
#define EE_TCOM_NODE_ADDR_WORD2 0x2
#define EE_VULCAN_PROD_ID 0x3
#define EE_MANUFACTURING_DATA 0x4
#define EE_SERIAL_NUMBER_WORD0 0x5
#define EE_SERIAL_NUMBER_WORD1 0x6
#define EE_MANUFACTURER_CODE 0x7
#define EE_ADDR_CONFIGURATION 0x8
#define EE_RESOURCE_CONFIGURATION 0x9
#define EE_OEM_NODE_ADDR_WORD0 0xA
#define EE_OEM_NODE_ADDR_WORD1 0xB
#define EE_OEM_NODE_ADDR_WORD2 0xC
#define EE_SOFTWARE_CONFIG_INFO 0xD
#define EE_CHECK_SUM 0xF
#define MIN_IO_BASE_ADDR 0x200
#define MAX_IO_BASE_ADDR 0x3F0
#define REGISTER_SET_SIZE 0x10
#define RX_STATUS_INCOMPLETE 0x8000
#define RX_STATUS_ERROR 0x4000
#define RX_STATUS_OVERRUN 0x08
#define RX_STATUS_RUNT 0x0b
#define TX_STATUS_COMPLETE 0x80
#define TX_STATUS_INTERRUPT 0x40
#define TX_STATUS_JABBER 0x20
#define TX_STATUS_UNDERRUN 0x10
#define TX_STATUS_MAX_COLLISION 0x08
#define TX_STATUS_TX_OVERFLOW 0x04
#define ELNK3_PACKET_COMPLETE(_RcvStatus) (!(((_RcvStatus) & RX_STATUS_INCOMPLETE)))
#define DWORDS_FROM_BYTES(_status) ((_status) >> 2)
#define BYTES_IN_FIFO(_status) ((ULONG)((_status) & 0x7ff))
#define BYTES_IN_FIFO_DW(_status) ((ULONG)((_status) & 0x7fc))
#define ELNK3_ROUND_TO_DWORD(x) (((x)+3) & 0xfffffffc)
#ifdef NDIS_NT
#ifndef IO_DBG
#define ELNK3_READ_PORT_USHORT(_pAdapt,offset) \
READ_PORT_USHORT((PUSHORT)(_pAdapt)->PortOffsets[(offset)]);
#define ELNK3_READ_PORT_USHORT_DIRECT(offset) \
READ_PORT_USHORT((PUSHORT)(offset));
#else
USHORT ELNK3_READ_PORT_USHORT( PVOID Adapter, ULONG Offset );
USHORT ELNK3_READ_PORT_USHORT_DIRECT( PVOID Offset );
#endif
#else
#define ELNK3_READ_PORT_USHORT(_pAdapt,offset) \
inpw((_pAdapt)->PortOffsets[(offset)]);
#define ELNK3_READ_PORT_USHORT_DIRECT(offset) \
inpw((offset));
#endif
#define ELNK3_COMMAND(_p,_c,_d) \
IF_IO_LOUD(DbgPrint("Writing command %d.%d\n", (USHORT)(_c), (USHORT)(_d));) \
NdisRawWritePortUshort((_p)->PortOffsets[PORT_CmdStatus], ((USHORT)(_c)<<11) | (_d))
#define ELNK3_SELECT_WINDOW(_p,_w) \
ELNK3_COMMAND(_p,(EC_SELECT_WINDOW),_w)
#define ELNK3_READ_STATUS(_pAdapt,_pData) \
NdisRawReadPortUshort((_pAdapt)->PortOffsets[PORT_CmdStatus],(_pData)); \
IF_IO_LOUD(DbgPrint("Read status %x\n", *(PUSHORT)(_pData));)
#define ELNK3_WAIT_NOT_BUSY(_pAdapt) { \
\
USHORT Status; \
ULONG Limit=1000; \
\
Status=ELNK3_READ_PORT_USHORT((_pAdapt),PORT_CmdStatus); \
\
while ((Status & 0x1000) && (--Limit>0)) { \
\
Status=ELNK3_READ_PORT_USHORT((_pAdapt),PORT_CmdStatus); \
} \
\
}
#define ELNK3WriteAdapterUchar(Adapter,PortOffset,UcharToWrite)\
IF_IO_LOUD(DbgPrint("Writing uchar %x to port %x\n", (UCHAR)(UcharToWrite), (PortOffset));) \
NdisRawWritePortUchar((Adapter)->PortOffsets[PortOffset],(UcharToWrite))
#define ELNK3WriteAdapterUshort(Adapter,PortOffset,UshortToWrite)\
IF_IO_LOUD(DbgPrint("Writing ushort %x to port %x\n", (USHORT)(UshortToWrite), (PortOffset));) \
NdisRawWritePortUshort((Adapter)->PortOffsets[PortOffset],(UshortToWrite))
#define ELNK3ReadAdapterUchar(Adapter,PortOffset,PUcharToRead)\
NdisRawReadPortUchar((Adapter)->PortOffsets[PortOffset],(PUcharToRead)); \
IF_IO_LOUD(DbgPrint("Read uchar %x from port %x\n", *(PUCHAR)(PUcharToRead), (PortOffset));) \
#define ELNK3ReadAdapterUshort(Adapter,PortOffset,PUshortToRead)\
NdisRawReadPortUshort((Adapter)->PortOffsets[PortOffset],(PUshortToRead)); \
IF_IO_LOUD(DbgPrint("Read ushort %x from port %x\n", *(PUSHORT)(PUshortToRead), (PortOffset));) \