xbox-kernel/private/ntos/xnet/enet/i82558.h
2020-09-30 17:17:25 +02:00

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