522 lines
16 KiB
C
522 lines
16 KiB
C
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
i82558.h
|
|
|
|
Abstract:
|
|
|
|
Intel 82558 NIC hardware related declarations
|
|
|
|
Revision History:
|
|
|
|
05/07/2000 davidx
|
|
Created it.
|
|
|
|
--*/
|
|
|
|
#ifndef _82558_H
|
|
#define _82558_H
|
|
|
|
//
|
|
// Vendor and device IDs for EPRO100+
|
|
//
|
|
#define NIC_VENDORID 0x8086
|
|
#define NIC_DEVICEID 0x1229
|
|
|
|
//------------------------------------------------------------------------
|
|
// I82558 command/status registers
|
|
//------------------------------------------------------------------------
|
|
|
|
typedef struct _NIC_CSR {
|
|
BYTE cusRus;
|
|
// CU and RU status
|
|
// Bit 7-6: CUS - CU status field
|
|
// 00 - idle
|
|
// 01 - suspended
|
|
// 10 - active
|
|
// 11 - * (reserved)
|
|
// Bit 5-2: RUS - RU status field
|
|
// 0000 - idle
|
|
// 0001 - suspended
|
|
// 0010 - no resources
|
|
// 0011 - *
|
|
// 0100 - ready
|
|
// 0101 - *
|
|
// 0110 - *
|
|
// 0111 - *
|
|
// 1000 - *
|
|
// 1001 - suspended with no more RBDs
|
|
// 1010 - No resources due to no more RBDs
|
|
// 1011 - *
|
|
// 1100 - ready with no RBDs present
|
|
// 1101 - *
|
|
// 1110 - *
|
|
// 1111 - *
|
|
// Bit 1-0: reserved
|
|
|
|
#define SCB_STAT_CUS(x) (((x) >> 6) & 3)
|
|
#define CUS_IDLE 0
|
|
#define CUS_SUSPENDED 1
|
|
#define CUS_ACTIVE 2
|
|
#define SCB_STAT_RUS(x) (((x) >> 2) & 0xf)
|
|
#define RUS_IDLE 0
|
|
#define RUS_SUSPENDED 1
|
|
#define RUS_NORES 2
|
|
#define RUS_READY 4
|
|
#define RUS_SUSPENDED_RBD 9
|
|
#define RUS_NORES_RBD 10
|
|
#define RUS_READY_RBD 12
|
|
|
|
BYTE statAck;
|
|
// Interrupt status and acknowledgement bits
|
|
// Bit 7: CX - CU finished executing a command with I-bit set
|
|
// Bit 6: FR - RU finished receiving a frame
|
|
// Bit 5: CNA - CU went from active to idle or suspended state
|
|
// Bit 4: RNR - RU left ready state
|
|
// Bit 3: MDI - MDI read or write cycle is done
|
|
// Bit 2: SWI - software generated an interrupt
|
|
// Bit 1: reserved
|
|
// Bit 0: FCP - flow control pause interrupt bit
|
|
|
|
#define SCB_STAT_CX BIT(7)
|
|
#define SCB_STAT_FR BIT(6)
|
|
#define SCB_STAT_CNA BIT(5)
|
|
#define SCB_STAT_RNR BIT(4)
|
|
#define SCB_STAT_MDI BIT(3)
|
|
#define SCB_STAT_SWI BIT(2)
|
|
#define SCB_STAT_FCP BIT(0)
|
|
|
|
BYTE cucRuc;
|
|
// Bit 7-4: CUC - CU command field
|
|
// 0000 - NOP
|
|
// 0001 - CU start
|
|
// 0010 - CU resume
|
|
// 0011 - *
|
|
// 0100 - load dump counters address
|
|
// 0101 - dump statistical counters
|
|
// 0110 - load CU base
|
|
// 0111 - dump and reset statistical counters
|
|
// 1000 - *
|
|
// 1001 - *
|
|
// 1010 - static resume
|
|
// 1011 - *
|
|
// ...
|
|
// 1111 - *
|
|
// Bit 3: reserved
|
|
// Bit 2-0: RU command field
|
|
// 000 - NOP
|
|
// 001 - RU start
|
|
// 010 - RU resume
|
|
// 011 - RU DMA redirect
|
|
// 100 - RU abort
|
|
// 101 - load header data size
|
|
// 110 - load RU base
|
|
// 111 - RBD resume
|
|
|
|
#define CUC_NOP (0 << 4)
|
|
#define CUC_START (1 << 4)
|
|
#define CUC_RESUME (2 << 4)
|
|
#define CUC_LOAD_DUMP_ADDR (4 << 4)
|
|
#define CUC_DUMP_STAT (5 << 4)
|
|
#define CUC_LOAD_CU_BASE (6 << 4)
|
|
#define CUC_DUMP_RESET_STAT (7 << 4)
|
|
#define CUC_STATIC_RESUME (10 << 4)
|
|
|
|
#define RUC_NOP 0
|
|
#define RUC_START 1
|
|
#define RUC_RESUME 2
|
|
#define RUC_RCVDMA_REDIRECT 3
|
|
#define RUC_ABORT 4
|
|
#define RUC_LOAD_HDS 5
|
|
#define RUC_LOAD_RU_BASE 6
|
|
#define RUC_RBD_RESUME 7
|
|
|
|
BYTE intrMask;
|
|
// Bit 7: CX interrupt mask bit
|
|
// Bit 6: FR interrupt mask bit
|
|
// Bit 5: CNA interrupt mask bit
|
|
// Bit 4: RNR interrupt mask bit
|
|
// Bit 3: ER interrupt mask bit
|
|
// Bit 2: FCP interrupt mask bit
|
|
// Bit 1: SI - software interrupt request
|
|
// Bit 0: M - global interrupt mask
|
|
|
|
#define CX_INTR_BIT BIT(7)
|
|
#define FR_INTR_BIT BIT(6)
|
|
#define CNA_INTR_BIT BIT(5)
|
|
#define RNR_INTR_BIT BIT(4)
|
|
#define ER_INTR_BIT BIT(3)
|
|
#define FCP_INTR_BIT BIT(2)
|
|
#define SW_INTR_BIT BIT(1)
|
|
#define INTR_MASK_BIT BIT(0)
|
|
|
|
DWORD scbGeneralPtr;
|
|
// SCB general pointer
|
|
|
|
DWORD port;
|
|
// PORT interface
|
|
// Bit 31-4: address bits
|
|
// Bit 3-0: port function selection
|
|
// 0000 - software reset
|
|
// 0001 - self-test
|
|
// 0010 - selective reset
|
|
// 0011 - dump
|
|
// 0100 - *
|
|
// ...
|
|
// 1111 - *
|
|
|
|
#define PORTCMD_SOFTWARE_RESET 0
|
|
#define PORTCMD_SELF_TEST 1
|
|
#define PORTCMD_SELECTIVE_RESET 2
|
|
#define PORTCMD_DUMP 3
|
|
|
|
WORD flashCtrl;
|
|
// Flash control register
|
|
|
|
WORD eepromCtrl;
|
|
// EEPROM control register
|
|
// Bit 7-4: reserved
|
|
// Bit 3: EEDO - data out
|
|
// Bit 2: EEDI - data in
|
|
// Bit 1: EECS - chip select
|
|
// Bit 0: EESK - serial clock
|
|
|
|
#define EEPROM_DO BIT(3)
|
|
#define EEPROM_DI BIT(2)
|
|
#define EEPROM_CS BIT(1)
|
|
#define EEPROM_SK BIT(0)
|
|
|
|
#define EEPROMOP_WRITE 1
|
|
#define EEPROMOP_READ 2
|
|
|
|
DWORD mdiCtrl;
|
|
// MDI control register
|
|
// Bit 31-30: reserved
|
|
// Bit 29: interrupt enable
|
|
// Bit 28: ready
|
|
// Bit 27-26: opcode
|
|
// 00 - *
|
|
// 01 - MDI write
|
|
// 10 - MDI read
|
|
// 11 - *
|
|
// Bit 25-21: PHY address
|
|
// Bit 20-16: PHY register address
|
|
// Bit 15-0: data field
|
|
|
|
#define MDI_INTR_ENABLE BIT(29)
|
|
#define MDI_READY BIT(28)
|
|
#define MDIOP_WRITE (1 << 26)
|
|
#define MDIOP_READ (2 << 26)
|
|
#define MDI_PHY_ADDR(x) ((x) << 21)
|
|
#define MDI_PHY_REG_ADDR(x) ((x) << 16)
|
|
|
|
DWORD reserved1;
|
|
DWORD reserved2;
|
|
// Bit 31-24: PMDR - power management driver register
|
|
// Bit 23-8: flow control register
|
|
// Bit 7-0: reserved
|
|
} volatile *PNIC_CSR;
|
|
|
|
extern PNIC_CSR NicCsr;
|
|
|
|
//------------------------------------------------------------------------
|
|
// 82558 general action command format
|
|
// NOTE: We store this information in the Packet.ifdata field
|
|
// of an outgoing packet. And it's tail-aligned so that it's
|
|
// contiguous with the packet data field.
|
|
//------------------------------------------------------------------------
|
|
|
|
typedef struct _ActionCmdBlock {
|
|
DWORD cmdstatus;
|
|
// Command and status:
|
|
// bit 31 (EL) - end of command block list
|
|
// bit 30 (S) - suspend after command completion
|
|
// bit 29 (I) - interrupt after command completion
|
|
// bit 28-19 - varies with different commands
|
|
// bit 18-16 (CMD) - command code
|
|
// bit 15 (C) - command completed
|
|
// bit 14 - reserved
|
|
// bit 13 - command executed ok
|
|
// bit 12-0 - varies with different commands
|
|
|
|
#define CMDFLAG_EL BIT(31)
|
|
#define CMDFLAG_S BIT(30)
|
|
#define CMDFLAG_I BIT(29)
|
|
|
|
#define ACTIONCMD_NOP (0 << 16)
|
|
#define ACTIONCMD_IA_SETUP (1 << 16)
|
|
#define ACTIONCMD_CONFIGURE (2 << 16)
|
|
#define ACTIONCMD_MC_SETUP (3 << 16)
|
|
#define ACTIONCMD_TRANSMIT (4 << 16)
|
|
#define ACTIONCMD_DUMP (6 << 16)
|
|
#define ACTIONCMD_DIAGNOSE (7 << 16)
|
|
|
|
#define CMDSTATUS_C BIT(15)
|
|
#define CMDSTATUS_OK BIT(13)
|
|
|
|
DWORD link;
|
|
// link to the next command block in the list
|
|
// this is a physical address
|
|
// use 0xffffffff at the end of the list
|
|
|
|
#define LINK_OFFSET_NULL 0xffffffff
|
|
|
|
} ActionCmdBlock;
|
|
|
|
//------------------------------------------------------------------------
|
|
// Transmit command block (TxCB)
|
|
//------------------------------------------------------------------------
|
|
|
|
typedef struct _TransmitCmdBlock {
|
|
ActionCmdBlock;
|
|
// General action command data:
|
|
// command / status
|
|
// link
|
|
// Additional command and status flags:
|
|
// bit 20 (NC) - no CRC and source address insertion
|
|
// bit 19 (SF) - simple or flexible mode
|
|
// bit 12 (U) - transmit underrun encountered
|
|
|
|
#define TxCBFLAG_NC BIT(20)
|
|
#define TxCBFLAG_SF BIT(19)
|
|
|
|
#define TxCBSTATUS_U BIT(12)
|
|
|
|
DWORD tbdArray;
|
|
// in flexible mode, physical address of the TBD array
|
|
|
|
WORD byteCount;
|
|
// bit 15 (EOF) - whole frame is kept inside the command block itself
|
|
// bit 14 - reserved
|
|
// bit 13-0: amount of data in the transmit command block itself
|
|
|
|
#define TxCB_EOF BIT(15)
|
|
|
|
BYTE txThreshold;
|
|
// number of bytes that should be present in the Tx FIFO
|
|
// before it starts transmitting the frame
|
|
|
|
BYTE tbdNumber;
|
|
// in flexible mode, represent the number of transmit buffers
|
|
// in the TBD array
|
|
} TransmitCmdBlock;
|
|
|
|
//
|
|
// Early transmit threshold
|
|
// This number is multiplied by 8 to get the actual byte count.
|
|
// BOGUS: Not sure why w2k driver uses such a high value which
|
|
// basically disables the early transmit feature.
|
|
//
|
|
#define DEFAULT_Tx_THRESHOLD 200
|
|
|
|
//
|
|
// Maximum number of TBD's for transmitting a single packet.
|
|
// This is not a hardware limit. Rather it's an arbitrary software
|
|
// limit we set. When there are two many fragments for a single
|
|
// packet, something upstream must be pretty bad and it's better
|
|
// to address the real issues there.
|
|
//
|
|
#define MAX_TBD_PER_XMIT 4
|
|
|
|
//
|
|
// TBD (Transmit Buffer Descriptor) entry
|
|
//
|
|
typedef struct _TBDEntry {
|
|
DWORD bufaddr;
|
|
// physical address of the buffer data
|
|
|
|
DWORD bufsize;
|
|
// bit 31-16: reserved
|
|
// bit 15 (EL): end of the TBD array
|
|
// bit 14: reserved
|
|
// bit 13-0: buffer size (in bytes)
|
|
} TBDEntry;
|
|
|
|
//------------------------------------------------------------------------
|
|
// Multicast setup command block
|
|
//------------------------------------------------------------------------
|
|
|
|
typedef struct _McastSetupCmdBlock {
|
|
ActionCmdBlock;
|
|
// General action command data:
|
|
// command / status
|
|
// link
|
|
|
|
WORD mcastCount;
|
|
// Number of multicast addresses to follow
|
|
|
|
BYTE mcastAddrs[ENETADDRLEN];
|
|
// variable number of Ethernet multicast addresses
|
|
} McastSetupCmdBlock;
|
|
|
|
//------------------------------------------------------------------------
|
|
// Individual address setup command block
|
|
//------------------------------------------------------------------------
|
|
|
|
typedef struct _IASetupCmdBlock {
|
|
ActionCmdBlock;
|
|
// General action command data:
|
|
// command / status
|
|
// link
|
|
|
|
BYTE hwaddr[ENETADDRLEN];
|
|
// Individual address
|
|
} IASetupCmdBlock;
|
|
|
|
//------------------------------------------------------------------------
|
|
// Configure command block
|
|
//------------------------------------------------------------------------
|
|
|
|
typedef struct _ConfigCmdBlock {
|
|
ActionCmdBlock;
|
|
// General action command data:
|
|
// command / status
|
|
// link
|
|
|
|
// Maximum number of configuration parameters
|
|
#define CONFIG_PARAM_COUNT 22
|
|
|
|
BYTE params[CONFIG_PARAM_COUNT];
|
|
// Configuration parameters
|
|
} ConfigCmdBlock;
|
|
|
|
//------------------------------------------------------------------------
|
|
// Receive frame descriptor (RFD)
|
|
//------------------------------------------------------------------------
|
|
|
|
typedef struct _RecvFrameDesc {
|
|
ActionCmdBlock;
|
|
// General action command data:
|
|
// command / status
|
|
// link
|
|
// Additional command and status flags:
|
|
// bit 20 (H) - indicate this RFD is a Header RFC
|
|
// bit 19 (SF) - simple or flexible mode
|
|
//
|
|
// bit 11 - CRC error in an aligned frame
|
|
// bit 10 - alignment error (number of bits is not 8x)
|
|
// bit 9 - ran out of buffer space - no resources
|
|
// bit 8 - DMA overrun - failed to acquire the system bus
|
|
// bit 7 - frame too short
|
|
// bit 5 - type/length: 1 for Ethernet frame, 0 for 802.3 frame
|
|
// bit 4 - receive error
|
|
// bit 2 - no address match
|
|
// bit 1 - IA match bit
|
|
// bit 0 - receive collision
|
|
|
|
#define RFDFLAG_H BIT(20)
|
|
#define RFDFLAG_SF BIT(19)
|
|
|
|
#define RFDSTATUS_CRC_ERROR BIT(11)
|
|
#define RFDSTATUS_ALIGN_ERROR BIT(10)
|
|
#define RFDSTATUS_NO_BUFFER BIT(9)
|
|
#define RFDSTATUS_DMA_OVERRUN BIT(8)
|
|
#define RFDSTATUS_SHORT_FRAME BIT(7)
|
|
#define RFDSTATUS_ENET_FRAME BIT(5)
|
|
#define RFDSTATUS_RECV_ERROR BIT(4)
|
|
#define RFDSTATUS_NOADDR_MATCH BIT(2)
|
|
#define RFDSTATUS_IA_MATCH BIT(1)
|
|
#define RFDSTATUS_COLLISION BIT(0)
|
|
|
|
DWORD rbdAddr;
|
|
// only used in flexible mode
|
|
// address of RBD (receive buffer descriptor)
|
|
|
|
WORD actualCount;
|
|
// bit 15 (EOF): set by 82558 when it writes data into the data area
|
|
// bit 14 (F): set by 82558 when it updates the actualCount field
|
|
// bit 13-0: number of bytes written into the data area
|
|
|
|
#define RFD_EOF BIT(15)
|
|
#define RFD_F BIT(14)
|
|
#define RFD_CNTMASK 0x3fff
|
|
|
|
WORD size;
|
|
// bit 15-14: reserved
|
|
// bit 13-0: size of the data buffer
|
|
} RecvFrameDesc;
|
|
|
|
//------------------------------------------------------------------------
|
|
// 82558 Statistical Counters
|
|
//------------------------------------------------------------------------
|
|
|
|
typedef struct _NicStatCounters {
|
|
DWORD xmitGoodFrames;
|
|
DWORD xmitMaxCollisionsErrors;
|
|
DWORD xmitLateCollisionsErrors;
|
|
DWORD xmitUnderrunErrors;
|
|
DWORD xmitLostCarrierSense;
|
|
DWORD xmitDeferred;
|
|
DWORD xmitSingleCollisions;
|
|
DWORD xmitMultipleCollisions;
|
|
DWORD xmitTotalCollisions;
|
|
DWORD recvGoodFrames;
|
|
DWORD recvCrcErrors;
|
|
DWORD recvAlignmentErrors;
|
|
DWORD recvResourceErrors;
|
|
DWORD recvOverrunErrors;
|
|
DWORD recvCollisionDetectErrors;
|
|
DWORD recvShortFrameErrors;
|
|
DWORD dumpCompletionStatus;
|
|
} NicStatCounters;
|
|
|
|
|
|
//
|
|
// We allocate a page of physically contiguous memory that's shared by
|
|
// the CPU and the NIC. This buffer is used for storing action command
|
|
// data (e.g. transmit command block and transmit buffer descriptor)
|
|
// that's passed to the NIC.
|
|
//
|
|
// start head tail last
|
|
// | | | |
|
|
// v v v v
|
|
// | xxxxxxxxxxxx |
|
|
//
|
|
// Note that we always leave at least one unit empty in the buffer.
|
|
// If head = tail, that means the whole buffer is empty.
|
|
//
|
|
typedef struct _NicCmdBuffer {
|
|
BYTE* start; // buffer base virtual address
|
|
BYTE* last; // points to after the buffer
|
|
BYTE* head; // points to the first busy entry
|
|
BYTE* tail; // points to the first free entry
|
|
UINT phyaddrOffset; // offset between virtual and physical address
|
|
} NicCmdBuffer;
|
|
|
|
// The smallest allocation unit is 8 bytes.
|
|
#define CMDBUF_ALLOC_UNIT 8
|
|
|
|
// Map virtual command buffer address to physical address
|
|
#define CmdBufferGetPhyAddr(nic, p) \
|
|
((UINT_PTR) (p) + (nic)->cmdbuf.phyaddrOffset)
|
|
|
|
//
|
|
// Extra header information at the beginning of the DMA packet
|
|
// that's used by the NIC for receiving frames:
|
|
// receive frame descriptor
|
|
//
|
|
#define RECVPKT_OVERHEAD sizeof(RecvFrameDesc)
|
|
|
|
//
|
|
// Allocate shared memory buffers for the NIC
|
|
//
|
|
#define NicAllocSharedMem(size) MmAllocateContiguousMemory(size)
|
|
#define NicFreeSharedMem(p) MmFreeContiguousMemory(p)
|
|
|
|
//
|
|
// Disable and enable NIC interrupts
|
|
//
|
|
INLINE VOID NicDisableInterrupt() {
|
|
NicCsr->intrMask = INTR_MASK_BIT;
|
|
}
|
|
|
|
INLINE VOID NicEnableInterrupt() {
|
|
NicCsr->intrMask = 0;
|
|
}
|
|
|
|
#endif // !_82558_H
|
|
|