diff --git a/drivers/network/dd/b57xx/CMakeLists.txt b/drivers/network/dd/b57xx/CMakeLists.txt index 32f00554708c6..e526488ea4c35 100644 --- a/drivers/network/dd/b57xx/CMakeLists.txt +++ b/drivers/network/dd/b57xx/CMakeLists.txt @@ -9,8 +9,7 @@ list(APPEND SOURCE hardware.c info.c interrupt.c - nic.h - send.c) + nic.h) add_library(b57xx MODULE ${SOURCE} b57xx.rc) add_pch(b57xx nic.h SOURCE) diff --git a/drivers/network/dd/b57xx/b57xxhw.h b/drivers/network/dd/b57xx/b57xxhw.h index 4e9a4999bbab0..51af21a6d2c08 100644 --- a/drivers/network/dd/b57xx/b57xxhw.h +++ b/drivers/network/dd/b57xx/b57xxhw.h @@ -2,21 +2,891 @@ * PROJECT: ReactOS Broadcom NetXtreme Driver * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: Hardware specific definitions - * COPYRIGHT: Copyright 2021 Scott Maday + * COPYRIGHT: Copyright 2021-2022 Scott Maday */ #pragma once #define IEEE_802_ADDR_LENGTH 6 -#define MAX_RESET_ATTEMPTS 10 -#define MAX_EEPROM_READ_ATTEMPTS 10000 - #define MAXIMUM_MULTICAST_ADDRESSES 16 +#define MAX_ATTEMPTS 1000 +#define MAX_ATTEMPTS_PHY 5000 + +#define NUM_RX_BUFFER_DESCRIPTORS 512 +#define NUM_RX_RETURN_DESCRIPTORS 1024 +#define NUM_TX_BUFFER_DESCRIPTORS 512 + +#define B57XX_ENDIAN_BYTESWAP 0 +#define B57XX_ENDIAN_WORDSWAP 1 +#define B57XX_ENDIAN_BYTESWAP_DATA 1 +#define B57XX_ENDIAN_WORDSWAP_DATA 1 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define B57XX_ENDIAN_BYTESWAP_NFDATA 0 +#define B57XX_ENDIAN_WORDSWAP_NFDATA 1 +#else +#define B57XX_ENDIAN_BYTESWAP_NFDATA 1 +#define B57XX_ENDIAN_WORDSWAP_NFDATA 1 +#endif + +#define B57XX_ENDIAN_SWAP(ByteSwap, ByteSwapReg, WordSwap, WordSwapReg) \ + ((ByteSwap ? ByteSwapReg : 0) | (WordSwap ? WordSwapReg : 0)) + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define B57XX_PAIRED_WORD(Word1, Word2) \ + struct \ + { \ + USHORT Word2; \ + USHORT Word1; \ + } +#else +#define B57XX_PAIRED_WORD(Word1, Word2) \ + struct \ + { \ + USHORT Word1; \ + USHORT Word2; \ + } +#endif + +#define BIT(x) (1 << x) + +typedef UCHAR MAC_ADDRESS[IEEE_802_ADDR_LENGTH], *PMAC_ADDRESS; + +#include + /* Ethernet frame header */ typedef struct _ETH_HEADER { - UCHAR Destination[IEEE_802_ADDR_LENGTH]; - UCHAR Source[IEEE_802_ADDR_LENGTH]; + MAC_ADDRESS Destination; + MAC_ADDRESS Source; USHORT PayloadType; } ETH_HEADER, *PETH_HEADER; + +/* B47XX NICs are big endian and need addresses in big endian format */ +typedef struct _B57XX_PHYSICAL_ADDRESS +{ + LONG HighPart; + ULONG LowPart; +} B57XX_PHYSICAL_ADDRESS, *PB57XX_PHYSICAL_ADDRESS; +C_ASSERT(sizeof(B57XX_PHYSICAL_ADDRESS) == 8); + +typedef struct _B57XX_RING_CONTROL_BLOCK +{ + B57XX_PHYSICAL_ADDRESS HostRingAddress; + B57XX_PAIRED_WORD + ( + MaxLength, + Flags + ); + ULONG NICRingAddress; +} B57XX_RING_CONTROL_BLOCK, *PB57XX_RING_CONTROL_BLOCK; + +typedef struct _B57XX_SEND_BUFFER_DESCRIPTOR +{ + B57XX_PHYSICAL_ADDRESS HostAddress; + B57XX_PAIRED_WORD + ( + Length, + Flags + ); + B57XX_PAIRED_WORD + ( + Reserved, + VLANTag + ); +} B57XX_SEND_BUFFER_DESCRIPTOR, *PB57XX_SEND_BUFFER_DESCRIPTOR; +C_ASSERT(sizeof(B57XX_SEND_BUFFER_DESCRIPTOR) == 16); + +typedef struct _B57XX_RECEIVE_BUFFER_DESCRIPTOR +{ + B57XX_PHYSICAL_ADDRESS HostAddress; + B57XX_PAIRED_WORD + ( + Index, + Length + ); + B57XX_PAIRED_WORD + ( + Type, + Flags + ); + B57XX_PAIRED_WORD + ( + IPChecksum, + TransportChecksum + ); + B57XX_PAIRED_WORD + ( + ErrorFlags, + VLANTag + ); + ULONG Reserved; + ULONG Opaque; +} B57XX_RECEIVE_BUFFER_DESCRIPTOR, *PB57XX_RECEIVE_BUFFER_DESCRIPTOR; +C_ASSERT(sizeof(B57XX_RECEIVE_BUFFER_DESCRIPTOR) == 32); + +typedef B57XX_PAIRED_WORD +( + SendConsumerIndex, // Send ring + ReceiveProducerIndex // Return ring +) B57XX_RING_INDEX_PAIR, *PB57XX_RING_INDEX_PAIR; + +typedef struct _B57XX_STATUS_BLOCK +{ + ULONG Status; + ULONG StatusTag; + B57XX_PAIRED_WORD + ( + ReceiveStandardConsumerIndex, + ReceiveJumboConsumerIndex // Unused + ); + B57XX_PAIRED_WORD + ( + Reserved, + ReceiveMiniConsumerIndex // Unused + ); + B57XX_RING_INDEX_PAIR RingIndexPairs[1]; +} B57XX_STATUS_BLOCK, *PB57XX_STATUS_BLOCK; +C_ASSERT(sizeof(B57XX_STATUS_BLOCK) == 20); + +typedef ULONG B57XX_STATISTICS_BLOCK[512], *PB57XX_STATISTICS_BLOCK; +C_ASSERT(sizeof(B57XX_STATISTICS_BLOCK) == 2048); + +#include + +/* Custom Blocks for general information and important hardware states */ + +typedef struct _B57XX_RECEIVE_PRODUCER_BLOCK +{ + B57XX_RING_CONTROL_BLOCK RingControlBlock; + PB57XX_RECEIVE_BUFFER_DESCRIPTOR pRing; // Virtual host address + ULONG Count; // Number of elements in the ring + ULONG Index; // Host producer index + PUCHAR HostBuffer; // Virtual host address + ULONG FrameBufferLength; // Aligned size of the buffer for each received frame +} B57XX_RECEIVE_PRODUCER_BLOCK, *PB57XX_RECEIVE_PRODUCER_BLOCK; + +typedef struct _B57XX_RECEIVE_CONSUMER_BLOCK +{ + B57XX_RING_CONTROL_BLOCK RingControlBlock; + PB57XX_RECEIVE_BUFFER_DESCRIPTOR pRing; // Virtual host address + ULONG Count; // Number of elements in the ring + ULONG Index; // Host consumer index (tail) +} B57XX_RECEIVE_CONSUMER_BLOCK, *PB57XX_RECEIVE_CONSUMER_BLOCK; + +typedef struct _B57XX_SEND_BLOCK +{ + B57XX_RING_CONTROL_BLOCK RingControlBlock; + PB57XX_SEND_BUFFER_DESCRIPTOR pRing; // Virtual host address + ULONG Count; // Number of elements in the ring + BOOLEAN RingFull; + PPNDIS_PACKET pPacketList; + ULONG ProducerIndex; // Host transmit send producer index (head) + ULONG ConsumerIndex; // Host completed transmission consumer index (tail) +} B57XX_SEND_BLOCK, *PB57XX_SEND_BLOCK; + +/* Devices */ + +typedef enum _B57XX_DEVICE_ID +{ + // Programmer's Guide: BCM57XX + B5700, + B5701, + B5702, + B5703C, + B5703S, + B5704C, + B5704S, + B5705, + B5705M, + B5788, + B5721, + B5751, + B5751M, + B5752, + B5752M, + B5714C, + B5714S, + B5715C, + B5715S, + // Programmer's Guide: BCM5756M + B5722, + B5755, + B5755M, + B5754, + B5754M, + B5756M, + B5757, + B5786, + B5787, + B5787M, + // Programmer's Guide: BCM5764M + B5784M, + B5764M, +} B57XX_DEVICE_ID, *PB57XX_DEVICE_ID; + +/* Ring Control Block Flags */ +#define B57XX_RCB_FLAG_USE_EXT_RECV_BD BIT(0) +#define B57XX_RCB_FLAG_RING_DISABLED BIT(1) + +/* Send Buffer Descriptor Flags */ +#define B57XX_SBD_TCP_UDP_CKSUM BIT(0) +#define B57XX_SBD_IP_CKSUM BIT(1) +#define B57XX_SBD_PACKET_END BIT(2) +#define B57XX_SBD_IP_FRAG BIT(3) +#define B57XX_SBD_IP_FRAG_END BIT(4) +#define B57XX_SBD_VLAN_TAG BIT(6) +#define B57XX_SBD_COAL_NOW BIT(7) +#define B57XX_SBD_CPU_PRE_DMA BIT(8) +#define B57XX_SBD_CPU_POST_DMA BIT(9) +#define B57XX_SBD_INSERT_SRC_ADDR BIT(12) +#define B57XX_SBD_DONT_GEN_CRC BIT(15) + +/* Receive Buffer Descriptor Flags */ +#define B57XX_RBD_PACKET_END BIT(2) +#define B57XX_RBD_BD_FLAG_JUMBO_RING BIT(5) +#define B57XX_RBD_VLAN_TAG BIT(6) +#define B57XX_RBD_FRAME_HAS_ERROR BIT(10) +#define B57XX_RBD_MINI_RING BIT(11) +#define B57XX_RBD_IP_CHECKSUM BIT(12) +#define B57XX_RBD_TCP_UDP_CHECKSUM BIT(13) +#define B57XX_RBD_TCP_UDP_IS_TCP BIT(14) + +/* Receive Buffer Descriptor Error Flags */ +#define B57XX_RBD_ERR_BAD_CRC BIT(0) +#define B57XX_RBD_ERR_COLL_DETECT BIT(1) +#define B57XX_RBD_ERR_LINK_LOST BIT(2) +#define B57XX_RBD_ERR_PHY_DECODE_ERR BIT(3) +#define B57XX_RBD_ERR_ODD_NIBBLE_RX_MII BIT(4) +#define B57XX_RBD_ERR_MAC_ABORT BIT(5) +#define B57XX_RBD_ERR_LEN_LESS_64 BIT(6) +#define B57XX_RBD_ERR_TRUNC_NO_RES BIT(7) +#define B57XX_RBD_ERR_GIANT_PKT_RCVD BIT(8) + +/* Status Block Status Word Flags */ +#define B57XX_SB_UPDATED BIT(0) +#define B57XX_SB_LINKSTATE BIT(1) +#define B57XX_SB_ERROR BIT(2) + +/* NIC Addresses */ +#define B57XX_ADDR_SEND_RCBS 0x0100 /* To 0x1FF */ +#define B57XX_ADDR_RECEIVE_RETURN_RCBS 0x0200 /* To 0x2FF */ +#define B57XX_ADDR_STAT_BLCK 0x0300 +#define B57XX_ADDR_STATUS_BLCK 0x0B00 +#define B57XX_ADDR_FW_MAILBOX 0x0B50 +#define B57XX_ADDR_FW_DRV_STATE_MAILBOX 0x0C04 +#define B57XX_ADDR_FW_DRV_WOL_MAILBOX 0x0D30 +#define B57XX_ADDR_SEND_RINGS 0x4000 +#define B57XX_ADDR_RECEIVE_STD_RINGS 0x6000 +#define B57XX_ADDR_RECEIVE_JUMBO_RINGS 0x7000 +#define B57XX_ADDR_RECEIVE_MINI_RINGS 0xE000 + +/* Memory Constants */ +#define B57XX_CONST_T3_MAGIC_NUMBER 0x4B657654 +#define B57XX_CONST_DRV_STATE_START 0x00000001 +#define B57XX_CONST_DRV_STATE_UNLOAD 0x00000002 +#define B57XX_CONST_DRV_STATE_WOL 0x00000003 +#define B57XX_CONST_DRV_STATE_SUSPEND 0x00000004 +#define B57XX_CONST_WOL_MAGIC_NUMBER 0x474C0000 + +/* Registers */ +#define B57XX_REG_VENDORID 0x0000 /* UShort */ +#define B57XX_REG_DEVICEID 0x0002 /* UShort */ +#define B57XX_REG_COMMAND 0x0004 /* UShort */ +#define B57XX_REG_CACHE_LINE_SIZE 0x000C /* UChar */ +#define B57XX_REG_SUBSY_VENDORID 0x002C /* UShort */ +#define B57XX_REG_CAPABILITY_PTR 0x0034 /* UChar */ +#define B57XX_REG_PCIX_COMMAND 0x0042 /* UShort */ +#define B57XX_REG_POWER_MANAGEMENT 0x004C /* UShort */ +#define B57XX_REG_HW_FIX 0x0066 /* UShort */ +#define B57XX_REG_MISC_HOST_CTRL 0x0068 /* ULong */ +#define B57XX_REG_DMA_CTRL 0x006C /* ULong */ +#define B57XX_REG_PCI_STATE 0x0070 /* ULong */ +#define B57XX_REG_PCI_CLOCK 0x0074 /* ULong */ +#define B57XX_REG_REG_BASE 0x0078 /* ULong */ +#define B57XX_REG_MEM_BASE 0x007C /* ULong */ +#define B57XX_REG_REG_DATA 0x0080 /* ULong */ +#define B57XX_REG_MEM_DATA 0x0084 /* ULong */ +#define B57XX_REG_DEVICE_CTRL 0x00D8 /* UShort */ +#define B57XX_REG_ADV_ERROR_CAPABILITY 0x0100 /* ULong */ +#define B57XX_REG_UNCORRET_ERROR_STATUS 0x0104 /* ULong */ +#define B57XX_REG_UNCORRET_ERROR_MASK 0x0108 /* ULong */ +#define B57XX_REG_UNCORRET_ERROR_SEVERE 0x010C /* ULong */ +#define B57XX_REG_CORRET_ERROR_STATUS 0x0110 /* ULong */ +#define B57XX_REG_CORRET_ERROR_MASK 0x0114 /* ULong */ +#define B57XX_REG_ADV_ERROR_CTRL 0x0118 /* ULong */ +#define B57XX_REG_ETH_MAC_MODE 0x0400 /* ULong */ +#define B57XX_REG_ETH_MAC_STATUS 0x0404 /* ULong */ +#define B57XX_REG_ETH_MAC_EVENT 0x0408 /* ULong */ +#define B57XX_REG_ETH_LED 0x040C /* ULong */ +#define B57XX_REG_ETH_MAC_ADDR1_HI 0x0410 /* ULong */ +#define B57XX_REG_ETH_MAC_ADDR1_LO 0x0414 /* ULong */ +#define B57XX_REG_ETH_MAC_ADDR2_HI 0x0418 /* ULong */ +#define B57XX_REG_ETH_MAC_ADDR2_LO 0x041C /* ULong */ +#define B57XX_REG_ETH_MAC_ADDR3_HI 0x0420 /* ULong */ +#define B57XX_REG_ETH_MAC_ADDR3_LO 0x0424 /* ULong */ +#define B57XX_REG_ETH_MAC_ADDR4_HI 0x0428 /* ULong */ +#define B57XX_REG_ETH_MAC_ADDR4_LO 0x042C /* ULong */ +#define B57XX_REG_ETH_TX_RND_BACKOFF 0x0438 /* ULong */ +#define B57XX_REG_ETH_RX_MTU_SIZE 0x043C /* ULong */ +#define B57XX_REG_ETH_MI_COMMUNICATION 0x044C /* ULong */ +#define B57XX_REG_ETH_MI_STATUS 0x0450 /* ULong */ +#define B57XX_REG_ETH_MI_MODE 0x0454 /* ULong */ +#define B57XX_REG_ETH_AUTOPOLL_STATUS 0x0458 /* ULong */ +#define B57XX_REG_ETH_TX_MODE 0x045C /* ULong */ +#define B57XX_REG_ETH_TX_STATUS 0x0460 /* ULong */ +#define B57XX_REG_ETH_TX_LENGTH 0x0464 /* ULong */ +#define B57XX_REG_ETH_RX_MODE 0x0468 /* ULong */ +#define B57XX_REG_ETH_RX_STATUS 0x046C /* ULong */ +#define B57XX_REG_ETH_MAC_HASH 0x0470 /* ULong, 4 of them to 0x047C */ +#define B57XX_REG_ETH_RX_RULES_CTRL 0x0480 /* ULong, 8 of them to 0x4B8 */ +#define B57XX_REG_ETH_RX_RULES_VALUE 0x0484 /* ULong, 8 of them to 0x4BC */ +#define B57XX_REG_ETH_RX_RULES_CONFIG 0x0500 /* ULong */ +#define B57XX_REG_ETH_RX_LOW_WM_MAX 0x0504 /* ULong */ +#define B57XX_REG_TX_DATA_MODE 0x0C00 /* ULong */ +#define B57XX_REG_TX_DATA_STAT_CTRL 0x0C08 /* ULong */ +#define B57XX_REG_TX_DATA_STAT_MASK 0x0C0C /* ULong */ +#define B57XX_REG_TX_COMPL_MODE 0x1000 /* ULong */ +#define B57XX_REG_TX_RING_SELECTOR_MODE 0x1400 /* ULong */ +#define B57XX_REG_TX_INITIATOR_MODE 0x1800 /* ULong */ +#define B57XX_REG_TX_BD_COMPL_MODE 0x1C00 /* ULong */ +#define B57XX_REG_RX_LIST_PLACE_MODE 0x2000 /* ULong */ +#define B57XX_REG_RX_LIST_PLACE_STATUS 0x2004 /* ULong */ +#define B57XX_REG_RX_LIST_PLACE_CONFIG 0x2010 /* ULong */ +#define B57XX_REG_RX_LIST_STAT_CTRL 0x2014 /* ULong */ +#define B57XX_REG_RX_LIST_STAT_MASK 0x2018 /* ULong */ +#define B57XX_REG_RX_DATA_BD_MODE 0x2400 /* ULong */ +#define B57XX_REG_RX_DATA_BD_STATUS 0x2404 /* ULong */ +#define B57XX_REG_JUMB_RXP_RING_HOST_HI 0x2440 /* ULong */ +#define B57XX_REG_JUMB_RXP_RING_HOST_LO 0x2444 /* ULong */ +#define B57XX_REG_JUMB_RXP_RING_ATTR 0x2448 /* ULong */ +#define B57XX_REG_JUMB_RXP_RING_NIC 0x244C /* ULong */ +#define B57XX_REG_STD_RXP_RING_HOST 0x2450 /* ULongLong */ +#define B57XX_REG_STD_RXP_RING_HOST_HI 0x2450 /* ULong */ +#define B57XX_REG_STD_RXP_RING_HOST_LO 0x2454 /* ULong */ +#define B57XX_REG_STD_RXP_RING_ATTR 0x2458 /* ULong */ +#define B57XX_REG_STD_RXP_RING_NIC 0x245C /* ULong */ +#define B57XX_REG_MINI_RXP_RING_HOST_HI 0x2460 /* ULong */ +#define B57XX_REG_MINI_RXP_RING_HOST_LO 0x2464 /* ULong */ +#define B57XX_REG_MINI_RXP_RING_ATTR 0x2468 /* ULong */ +#define B57XX_REG_MINI_RXP_RING_NIC 0x246C /* ULong */ +#define B57XX_REG_RX_DATA_COMPL_MODE 0x2800 /* ULong */ +#define B57XX_REG_RX_BD_MODE 0x2C00 /* ULong */ +#define B57XX_REG_MINI_RXP_RING_REPL 0x2C14 /* ULong */ +#define B57XX_REG_STD_RX_RING_REPL 0x2C18 /* ULong */ +#define B57XX_REG_JUMBO_RX_RING_REPL 0x2C1C /* ULong */ +#define B57XX_REG_RX_BD_COMPL_MODE 0x3000 /* ULong */ +#define B57XX_REG_RX_BD_COMPL_STATUS 0x3004 /* ULong */ +#define B57XX_REG_JUMBO_RXP_INDEX 0x3008 /* ULong */ +#define B57XX_REG_STD_RXP_INDEX 0x300C /* ULong */ +#define B57XX_REG_MINI_RXP_INDEX 0x3010 /* ULong */ +#define B57XX_REG_MBUF_CLUSTER_FREE 0x3800 /* ULong */ +#define B57XX_REG_COAL_HOST_MODE 0x3C00 /* ULong */ +#define B57XX_REG_COAL_HOST_STATUS 0x3C04 /* ULong */ +#define B57XX_REG_COAL_RX_TICKS 0x3C08 /* ULong */ +#define B57XX_REG_COAL_TX_TICKS 0x3C0C /* ULong */ +#define B57XX_REG_COAL_RX_MAX_BD 0x3C10 /* ULong */ +#define B57XX_REG_COAL_TX_MAX_BD 0x3C14 /* ULong */ +#define B57XX_REG_COAL_RX_INT_TICKS 0x3C18 /* ULong */ +#define B57XX_REG_COAL_TX_INT_TICKS 0x3C1C /* ULong */ +#define B57XX_REG_COAL_RX_MAX_INT_BD 0x3C20 /* ULong */ +#define B57XX_REG_COAL_TX_MAX_INT_BD 0x3C24 /* ULong */ +#define B57XX_REG_STAT_TICKS 0x3C28 /* ULong */ +#define B57XX_REG_STAT_HOST_ADDR 0x3C30 /* ULongLong */ +#define B57XX_REG_STATUS_BLCK_HOST_ADDR 0x3C38 /* ULongLong */ +#define B57XX_REG_STAT_BASE_ADDR 0x3C40 /* ULong */ +#define B57XX_REG_STATUS_BLCK_BASE_ADDR 0x3C44 /* ULong */ +#define B57XX_REG_FLOW_ATTENTION 0x3C48 /* ULong */ +#define B57XX_REG_RX_LIST_SELECT_MODE 0x3400 /* ULong */ +#define B57XX_REG_RX_LIST_SELECT_STATUS 0x3404 /* ULong */ +#define B57XX_REG_MEM_ARB_MODE 0x4000 /* ULong */ +#define B57XX_REG_MEM_ARB_STATUS 0x4004 /* ULong */ +#define B57XX_REG_MEM_ARB_TRAP_LO 0x4008 /* ULong */ +#define B57XX_REG_MEM_ARB_TRAP_HI 0x400C /* ULong */ +#define B57XX_REG_BUF_MAN_MODE 0x4400 /* ULong */ +#define B57XX_REG_BUF_MAN_STATUS 0x4404 /* ULong */ +#define B57XX_REG_MBUF_POOL_BASE 0x4408 /* ULong */ +#define B57XX_REG_MBUF_POOL_LENGTH 0x440C /* ULong */ +#define B57XX_REG_MBUF_POOL_DMA_LO_WM 0x4410 /* ULong */ +#define B57XX_REG_MBUF_POOL_RX_LO_WM 0x4414 /* ULong */ +#define B57XX_REG_MBUF_POOL_HI_WM 0x4418 /* ULong */ +#define B57XX_REG_DMA_DESC_POOL_BASE 0x442C /* ULong */ +#define B57XX_REG_DMA_DESC_POOL_LENGTH 0x4430 /* ULong */ +#define B57XX_REG_DMA_DESC_POOL_LO_WM 0x4434 /* ULong */ +#define B57XX_REG_DMA_DESC_POOL_HI_WM 0x4438 /* ULong */ +#define B57XX_REG_DMA_WRITE_MODE 0x4C00 /* ULong */ +#define B57XX_REG_DMA_READ_MODE 0x4800 /* ULong */ +#define B57XX_REG_DMA_READ_STATUS 0x4804 /* ULong */ +#define B57XX_REG_DMA_WRITE_STATUS 0x4C04 /* ULong */ +#define B57XX_REG_RX_RISC_MODE 0x5000 /* ULong */ +#define B57XX_REG_RX_RISC_STATE 0x5004 /* ULong */ +#define B57XX_REG_TX_RISC_MODE 0x5400 /* ULong */ +#define B57XX_REG_TX_RISC_STATE 0x5404 /* ULong */ +#define B57XX_REG_FTQ_RESET 0x5C00 /* ULong */ +#define B57XX_REG_MSI_MODE 0x6000 /* ULong */ +#define B57XX_REG_MSI_STATUS 0x6004 /* ULong */ +#define B57XX_REG_MSI_FIFO 0x6008 /* ULong */ +#define B57XX_REG_DMA_COMPLETION 0x6400 /* ULong */ +#define B57XX_REG_MODE_CTRL 0x6800 /* ULong */ +#define B57XX_REG_MISC_CONFIG 0x6804 /* ULong */ +#define B57XX_REG_MISC_LOCAL_CTRL 0x6808 /* ULong */ +#define B57XX_REG_TIMER 0x680C /* ULong */ +#define B57XX_REG_RX_RISC_EVENT 0x6810 /* ULong */ +#define B57XX_REG_TX_RISC_EVENT 0x6820 /* ULong */ +#define B57XX_REG_RX_CPU_EVENT 0x684C /* ULong */ +#define B57XX_REG_FASTBOOT_COUNTER 0x6894 /* ULong */ +#define B57XX_REG_ASF_CTRL 0x6C00 /* ULong */ +#define B57XX_REG_ASF_HEARTBEAT 0x6C10 /* ULong */ +#define B57XX_REG_NVM_COMMAND 0x7000 /* ULong */ +#define B57XX_REG_NVM_WRITE 0x7008 /* ULong */ +#define B57XX_REG_NVM_ADDRESS 0x700C /* ULong */ +#define B57XX_REG_NVM_READ 0x7010 /* ULong */ +#define B57XX_REG_NVM_CONFIG1 0x7014 /* ULong */ +#define B57XX_REG_NVM_CONFIG2 0x7018 /* ULong */ +#define B57XX_REG_NVM_CONFIG3 0x701C /* ULong */ +#define B57XX_REG_SOFT_ARB 0x7020 /* ULong */ +#define B57XX_REG_NVM_ACCESS 0x7024 /* ULong */ +#define B57XX_REG_NVM_WRITE1 0x7028 /* ULong */ +#define B57XX_REG_NVM_ARB_WATCH 0x702C /* ULong */ +#define B57XX_REG_TLP_CTRL 0x7C00 /* ULong */ +#define B57XX_REG_DATA_LINK_CTRL 0x7D00 /* ULong */ +#define B57XX_REG_DATA_LINK_STATUS 0x7D04 /* ULong */ +#define B57XX_REG_DATA_LINK_ATTN 0x7D08 /* ULong */ +#define B57XX_REG_DATA_LINK_ATTN_MASK 0x7D0C /* ULong */ +#define B57XX_REG_TLP_ERROR_COUNTER 0x7D40 /* ULong */ +#define B57XX_REG_MEM_WINDOW 0x8000 /* To 0xffff */ + +/* High priority mailbox registers */ +#define B57XX_MBOX_INT_MAILBOX0 0x200 +#define B57XX_MBOX_STD_RXP_RING_INDEX 0x268 +#define B57XX_MBOX_JUMBO_RXP_RING_INDEX 0x270 +#define B57XX_MBOX_MINI_RXP_RING_INDEX 0x278 +#define B57XX_MBOX_RXC_RET_RING_INDEX1 0x280 +#define B57XX_MBOX_TXP_HOST_RING_INDEX1 0x300 +#define B57XX_MBOX_TXP_HOST_RING_INDEX2 0x308 +#define B57XX_MBOX_TXP_HOST_RING_INDEX3 0x310 +#define B57XX_MBOX_TXP_HOST_RING_INDEX4 0x318 +#define B57XX_MBOX_TXP_HOST_RING_INDEX4 0x318 +#define B57XX_MBOX_TXP_NIC_RING_INDEX1 0x380 + +/* B57XX_COMMAND */ +#define B57XX_COMMAND_MEMSPACE BIT(1) /* Memory Space, R/W */ +#define B57XX_COMMAND_BUSMASTER BIT(2) /* Bus Master, R/W */ +#define B57XX_COMMAND_PARITY BIT(6) /* Parity Error Enable, R/W */ +#define B57XX_COMMAND_SYSERROR BIT(8) /* System Error Enable, R/W */ +#define B57XX_COMMAND_INTDISABLE BIT(10) /* Interrupt Disable, R/W for supported devices */ + +/* B57XX_PCIX_COMMAND */ +#define B57XX_PCIX_COMMAND_RELAXEDORDER BIT(1) /* Enable Relaxed Ordering, R/W */ + +/* B57XX_POWER_MANAGEMENT */ +#define B57XX_POWER_MANAGEMENT_STATE_D0 (0b00 << 0) /* Power State D0, R/W */ +#define B57XX_POWER_MANAGEMENT_STATE_D1 (0b01 << 0) /* Power State D1, R/W */ +#define B57XX_POWER_MANAGEMENT_STATE_D2 (0b10 << 0) /* Power State D2, R/W */ +#define B57XX_POWER_MANAGEMENT_STATE_D3 (0b11 << 0) /* Power State D3, R/W */ +#define B57XX_POWER_MANAGEMENT_PMEENABLE BIT(8) /* PME Enable, R/O */ +#define B57XX_POWER_MANAGEMENT_PMESTATUS BIT(15) /* PME Status, R/W2C */ + +/* B57XX_HW_FIX */ +#define B57XX_HW_FIX_HWFIX1 BIT(10) /* HW Fix 1, R/W */ +#define B57XX_HW_FIX_HWFIX2 BIT(11) /* HW Fix 2, R/W */ +#define B57XX_HW_FIX_HWFIX3 BIT(12) /* HW Fix 3, R/W */ +#define B57XX_HW_FIX_HWFIX4 BIT(13) /* HW Fix 4, R/W */ + +/* B57XX_MISC_HOST_CTRL */ +#define B57XX_MISC_HOST_CTRL_CINTA BIT(0) /* Clear Interrupt INTA, W/O */ +#define B57XX_MISC_HOST_CTRL_MASKINTOUT BIT(1) /* Mask PCI Interrupt Output, R/W */ +#define B57XX_MISC_HOST_CTRL_ENDIANBYTESWAP BIT(2) /* Enable Endian Byte Swap, R/W */ +#define B57XX_MISC_HOST_CTRL_ENDIANWORDSWAP BIT(3) /* Enable Endian Word Swap, R/W */ +#define B57XX_MISC_HOST_CTRL_PCISTATE BIT(4) /* PCI State Register capability, R/W */ +#define B57XX_MISC_HOST_CTRL_CLOCKCTRL BIT(5) /* Clock Control Register capability, R/W */ +#define B57XX_MISC_HOST_CTRL_INDIRECTACCESS BIT(7) /* Enable Indirect Access, R/W */ +#define B57XX_MISC_HOST_CTRL_MASKINTMODE BIT(8) /* Mask Interrupt Mode, R/W */ +#define B57XX_MISC_HOST_CTRL_TAGGEDSTATUS BIT(9) /* Tagged Status, R/W for supported devices */ + +/* B57XX_REG_DMA_CTRL */ +#define B57XX_DMA_CTRL_DPWB_64 (0b00 << 29) /* Df PCI Wr Cmd bnd: 64 bytes, R/W for s. dev. */ +#define B57XX_DMA_CTRL_DPWB_128 (0b01 << 29) /* Df PCI Wr Cmd bnd: 128 bytes, R/W for s. dev. */ +#define B57XX_DMA_CTRL_DPWB_NOC (0b10 << 29) /* Df PCI Wr Cmd bnd: No bound, R/W for s. dev. */ + +/* B57XX_PCI_STATE */ +#define B57XX_PCI_STATE_FORCERESET BIT(0) /* Force PCI Reset, R/O */ +#define B57XX_PCI_STATE_INTSTATE BIT(1) /* Interrupt State, R/O */ +#define B57XX_PCI_STATE_BUSMODE BIT(2) /* PCI bus Mode, R/O */ +#define B57XX_PCI_STATE_HIGHSPEED BIT(3) /* 33/66 MHz PCI bus, 66/133 MHz PCI-X bus, R/O */ +#define B57XX_PCI_STATE_32BITBUS BIT(4) /* 32-bit PCI bus, R/O */ + +/* B57XX_PCI_CLOCK */ +#define B57XX_PCI_CLOCK_ALTCLOCKFINAL BIT(20) /* Select Final Alt Clock, R/W */ +#define B57XX_PCI_CLOCK_ALTCLOCK BIT(12) /* Select Alt Clock, R/W */ + +/* B57XX_ETH_MAC_MODE */ +#define B57XX_ETH_MAC_MODE_RESET BIT(0) /* Global Reset, R/W */ +#define B57XX_ETH_MAC_MODE_HALFDUPLEX BIT(1) /* Half-duplex, R/W */ +#define B57XX_MASK_ETH_MAC_MODE_PORT (0b11 << 2) /* Port mode */ +#define B57XX_ETH_MAC_MODE_PORT_NONE (0b00 << 2) /* Port mode: None, R/W */ +#define B57XX_ETH_MAC_MODE_PORT_MII (0b01 << 2) /* Port mode: MII, R/W */ +#define B57XX_ETH_MAC_MODE_PORT_GMI (0b10 << 2) /* Port mode: GMI, R/W */ +#define B57XX_ETH_MAC_MODE_PORT_TBI (0b11 << 2) /* Port mode: Ten bit interface, R/W */ +#define B57XX_ETH_MAC_MODE_LOOPBACK BIT(4) /* Loopback Mode, R/W */ +#define B57XX_ETH_MAC_MODE_TAGGED BIT(7) /* Tagged MAC Control, R/W */ +#define B57XX_ETH_MAC_MODE_TXBURST BIT(8) /* Enable TX Bursting, R/W */ +#define B57XX_ETH_MAC_MODE_MAXDEFER BIT(9) /* Max Deferral checking statistic, R/W */ +#define B57XX_ETH_MAC_MODE_LINKPOLARITY BIT(10) /* Link polarity, R/W for supported devices */ +#define B57XX_ETH_MAC_MODE_RXSTATENABLE BIT(11) /* Enable RX Statistics, R/W */ +#define B57XX_ETH_MAC_MODE_RXSTATCLEAR BIT(12) /* Clear RX Statistics, R/W */ +#define B57XX_ETH_MAC_MODE_RXSTATFLUSH BIT(13) /* Flush RX Statistics, R/W */ +#define B57XX_ETH_MAC_MODE_TXSTATENABLE BIT(14) /* Enable TX Statistics, R/W */ +#define B57XX_ETH_MAC_MODE_TXSTATCLEAR BIT(15) /* Clear TX Statistics, R/W */ +#define B57XX_ETH_MAC_MODE_TXSTATFLUSH BIT(16) /* Flush TX Statistics, R/W */ +#define B57XX_ETH_MAC_MODE_SENDCONFIGS BIT(17) /* Send Configs, R/W */ +#define B57XX_ETH_MAC_MODE_MAGICDETECT BIT(18) /* Magic Packet Detect Enable, R/W */ +#define B57XX_ETH_MAC_MODE_ACPIPOWERON BIT(19) /* ACPI Power-on Enable, R/W */ +#define B57XX_ETH_MAC_MODE_MIP BIT(20) /* Enable MIP, R/W for supported devices */ +#define B57XX_ETH_MAC_MODE_TXDMA BIT(21) /* Enable Transmit DMA engine, R/W */ +#define B57XX_ETH_MAC_MODE_RXDMA BIT(22) /* Enable Receive DMA engine, R/W */ +#define B57XX_ETH_MAC_MODE_RXFHDDMA BIT(23) /* Enable RX Frame Header DMA engine, R/W */ + +/* B57XX_ETH_MAC_STATUS */ +#define B57XX_ETH_MAC_STATUS_CONFIGCHANGED BIT(3) /* Config changed, W2C for supported devices */ +#define B57XX_ETH_MAC_STATUS_SYNCCHANGED BIT(4) /* Sync changed, W2C for supported devices */ +#define B57XX_ETH_MAC_STATUS_PORTDECODEERR BIT(10) /* Port Decode Error, W2C for supported dev. */ +#define B57XX_ETH_MAC_STATUS_MICOMPLETE BIT(22) /* MI Completion, W2C */ +#define B57XX_ETH_MAC_STATUS_RXSTATOR BIT(26) /* RX Statistics Overrun, W2C */ +#define B57XX_ETH_MAC_STATUS_TXSTATOR BIT(27) /* TX Statistics Overrun, W2C */ +#define B57XX_ETH_MAC_STATUS_INTEREST BIT(28) /* Interesting Packet Attn, W2C for s. dev. */ + +/* B57XX_ETH_MAC_EVENT */ +#define B57XX_ETH_MAC_EVENT_PORTERROR BIT(10) /* Port Decode Error, R/W for supported devices */ +#define B57XX_ETH_MAC_EVENT_LINKSTATE BIT(12) /* Link State Changed, R/W */ +#define B57XX_ETH_MAC_EVENT_MICOMPLETE BIT(22) /* MI Completion, R/W */ +#define B57XX_ETH_MAC_EVENT_MIINT BIT(23) /* MI Interrupt, R/W */ +#define B57XX_ETH_MAC_EVENT_APERROR BIT(24) /* AP Error, R/W */ +#define B57XX_ETH_MAC_EVENT_ODIERROR BIT(25) /* ODI Error, R/W */ +#define B57XX_ETH_MAC_EVENT_RXSTATOR BIT(26) /* RX Statistics Overrun, R/W */ +#define B57XX_ETH_MAC_EVENT_TXSTATOR BIT(27) /* TX Statistics Overrun, R/W */ +#define B57XX_ETH_MAC_EVENT_INTEREST BIT(28) /* Interesting Packet PME Attn, R/W for s. dev. */ + +/* B57XX_ETH_MI_COMMUNICATION */ +#define B57XX_ETH_MI_COMMUNICATION_READFAIL BIT(28) /* Read failed, R/W */ +#define B57XX_ETH_MI_COMMUNICATION_START BIT(29) /* Start/Busy, R/W */ + +/* B57XX_ETH_MI_STATUS */ +#define B57XX_ETH_MI_STATUS_LINK BIT(0) /* Link status, R/W */ +#define B57XX_ETH_MI_STATUS_10MBPS BIT(1) /* Mode10 Mbps, R/W */ + +/* B57XX_ETH_MI_MODE */ +#define B57XX_ETH_MI_MODE_SHORTPREAMBLE BIT(1) /* Use Short Preamble, R/W */ +#define B57XX_ETH_MI_MODE_PORTPOLLING BIT(4) /* Port Polling, R/W */ + +/* B57XX_ETH_TX_MODE */ +#define B57XX_ETH_TX_MODE_RESET BIT(0) /* Reset, R/W */ +#define B57XX_ETH_TX_MODE_ENABLE BIT(1) /* Enable, R/W */ +#define B57XX_ETH_TX_MODE_FLOWCTRL BIT(4) /* Enable Flow Contro, R/W */ +#define B57XX_ETH_TX_MODE_BIGBACKOFF BIT(5) /* Enable Big Backoff, R/W */ +#define B57XX_ETH_TX_MODE_LONGPAUSE BIT(6) /* Enable Long Pause, R/W */ +#define B57XX_ETH_TX_MODE_LOCKUPFIX BIT(8) /* Lockup fix, R/W */ + +/* B57XX_ETH_RX_MODE */ +#define B57XX_ETH_RX_MODE_RESET BIT(0) /* Reset, R/W */ +#define B57XX_ETH_RX_MODE_ENABLE BIT(1) /* Enable, R/W */ +#define B57XX_ETH_RX_MODE_FLOWCTRL BIT(2) /* Enable Flow Control, R/W */ +#define B57XX_ETH_RX_MODE_KEEPPAUSE BIT(4) /* Keep Pause, R/W */ +#define B57XX_ETH_RX_MODE_OVERSIZED BIT(5) /* Accept Oversized, R/W for supported devices */ +#define B57XX_ETH_RX_MODE_RUNTS BIT(6) /* Accept Runts, R/W */ +#define B57XX_ETH_RX_MODE_LENGTHCHECK BIT(7) /* Length Check, R/W */ +#define B57XX_ETH_RX_MODE_PROMISCUOUS BIT(8) /* Promiscuous Mode, R/W */ +#define B57XX_ETH_RX_MODE_NOCRCCHECK BIT(9) /* No CRC Check, R/W */ +#define B57XX_ETH_RX_MODE_KEEPVLAN BIT(10) /* Keep VLAN Tag Diag Mode, R/W */ +#define B57XX_ETH_RX_MODE_FILTBROAD BIT(11) /* Filter broadcast, R/W for supported devices */ +#define B57XX_ETH_RX_MODE_EXTHASH BIT(12) /* Extended Hash Enable, R/W for supported dev. */ + +/* B57XX_ETH_RX_RULES_CTRL */ +#define B57XX_MASK_ETH_RX_RULES_CTRL_OFFSET (0xFF << 0) /* Offset, R/W */ +#define B57XX_MASK_ETH_RX_RULES_CTRL_CLASS (0x1F << 8) /* Class, R/W */ +#define B57XX_ETH_RX_RULES_CTRL_HEADER_FRAME (0b000 << 13) /* Start of Frame header, R/W */ +#define B57XX_ETH_RX_RULES_CTRL_HEADER_IP (0b001 << 13) /* Start of IP Header, R/W */ +#define B57XX_ETH_RX_RULES_CTRL_HEADER_TCP (0b010 << 13) /* Start of TCP Header, R/W */ +#define B57XX_ETH_RX_RULES_CTRL_HEADER_UDP (0b011 << 13) /* Start of UDP Header, R/W */ +#define B57XX_ETH_RX_RULES_CTRL_HEADER_DATA (0b100 << 13) /* Start of Data, R/W */ +#define B57XX_ETH_RX_RULES_CTRL_CMP_EQUAL (0b00 << 16) /* Equal compare op., R/W */ +#define B57XX_ETH_RX_RULES_CTRL_CMP_NOTEQUAL (0b01 << 16) /* Not equal compare op., R/W */ +#define B57XX_ETH_RX_RULES_CTRL_CMP_GREATER (0b10 << 16) /* Greater than compare op, R/W */ +#define B57XX_ETH_RX_RULES_CTRL_CMP_LESS (0b11 << 16) /* Less than compare op., R/W */ +#define B57XX_ETH_RX_RULES_CTRL_MAP BIT(24) /* Map, R/W */ +#define B57XX_ETH_RX_RULES_CTRL_DISCARD BIT(25) /* Discard, R/W */ +#define B57XX_ETH_RX_RULES_CTRL_MASK BIT(26) /* Mask, R/W */ +#define B57XX_ETH_RX_RULES_CTRL_PROCESSOR3 BIT(27) /* Processor 3, R/W for s. dev. */ +#define B57XX_ETH_RX_RULES_CTRL_PROCESSOR2 BIT(28) /* Processor 2, R/W for s. dev. */ +#define B57XX_ETH_RX_RULES_CTRL_PROCESSOR1 BIT(29) /* Processor 1, R/W */ +#define B57XX_ETH_RX_RULES_CTRL_NEXT BIT(30) /* And With Next, R/W */ +#define B57XX_ETH_RX_RULES_CTRL_ENABLE BIT(31) /* Enable R/W */ + +/* B57XX_ETH_RX_RULES_VALUE */ +#define B57XX_MASK_ETH_RX_RULES_VALUE_VALUE (0xffff << 0) /* Value, R/W */ +#define B57XX_MASK_ETH_RX_RULES_VALUE_MASK (0xffff << 16) /* Mask, R/W */ + +/* B57XX_ETH_RX_RULES_CONFIG */ +#define B57XX_MASK_ETH_RX_RULES_CONFIG_NORULECLASS (0xf << 3) /* No Rules Matches Default Class */ + +/* B57XX_TX_DATA_MODE */ +#define B57XX_TX_DATA_MODE_RESET BIT(0) /* Reset, R/W */ +#define B57XX_TX_DATA_MODE_ENABLE BIT(1) /* Enable, R/W */ + +/* B57XX_TX_COMPL_MODE */ +#define B57XX_TX_COMPL_MODE_RESET BIT(0) /* Reset, R/W */ +#define B57XX_TX_COMPL_MODE_ENABLE BIT(1) /* Enable, R/W */ +#define B57XX_TX_COMPL_MODE_LBDBRFIX BIT(2) /* Long BD Burst Read Fix, R/W for supported dev. */ + +/* B57XX_RX_LIST_PLACE_MODE */ +#define B57XX_RX_LIST_PLACE_MODE_RESET BIT(0) /* Reset, R/W */ +#define B57XX_RX_LIST_PLACE_MODE_ENABLE BIT(1) /* Enable, R/W */ +#define B57XX_RX_LIST_PLACE_MODE_CLASSZERO BIT(2) /* Class Zero Attention Enable, R/W */ +#define B57XX_RX_LIST_PLACE_MODE_MAPOOR BIT(3) /* Mapping Out of Range Attention Enable, R/W */ +#define B57XX_RX_LIST_PLACE_MODE_STATSOVER BIT(4) /* Stats Overflow Attention Enable, R/W */ + +/* B57XX_RX_DATA_BD_MODE */ +#define B57XX_RX_DATA_BD_MODE_RESET BIT(0) /* Reset, R/W */ +#define B57XX_RX_DATA_BD_MODE_ENABLE BIT(1) /* Enable, R/W */ +#define B57XX_RX_DATA_BD_MODE_JUMBORXBD BIT(2) /* Jumbo RX needed & ring dis., R/W for s. dev. */ +#define B57XX_RX_DATA_BD_MODE_OVERSIZED BIT(3) /* Frame size too large to fit into 1 RX BD, R/W */ +#define B57XX_RX_DATA_BD_MODE_ILLEGALSZ BIT(4) /* Illegal return ring size, R/W */ +#define B57XX_RX_DATA_BD_MODE_RDITIMER BIT(7) /* RDI Timer Event Enable, R/W for supported dev. */ + +/* B57XX_BUF_MAN_MODE */ +#define B57XX_BUF_MAN_MODE_RESET BIT(0) /* Reset, R/W */ +#define B57XX_BUF_MAN_MODE_ENABLE BIT(1) /* Enable, R/W */ +#define B57XX_BUF_MAN_MODE_ATTN BIT(2) /* Attention Enable, R/W */ +#define B57XX_BUF_MAN_MODE_BMTEST BIT(3) /* BM Test Mode, R/W */ +#define B57XX_BUF_MAN_MODE_LOATTN BIT(4) /* MBUF Low Attn Enable, R/W */ + +/* B57XX_DMA_MODE */ +#define B57XX_DMA_MODE_RESET BIT(0) /* Reset, R/W */ +#define B57XX_DMA_MODE_ENABLE BIT(1) /* Enable, R/W */ +#define B57XX_DMA_MODE_TARGETABORT BIT(2) /* PCI Target Abort Attention Enable, R/W */ +#define B57XX_DMA_MODE_MASTERABORT BIT(3) /* PCI Master Abort Attention Enable, R/W */ +#define B57XX_DMA_MODE_PARITYERROR BIT(4) /* PCI Parity Error Attention Enable, R/W */ +#define B57XX_DMA_MODE_HOSTADDROF BIT(5) /* PCI Host Address Overflow Error Attention, R/W */ +#define B57XX_DMA_MODE_FIFOOR BIT(6) /* PCI FIFO Overrun Attention Enable, R/W */ +#define B57XX_DMA_MODE_FIFOUR BIT(7) /* PCI FIFO Underrun Attention Enable, R/W */ +#define B57XX_DMA_MODE_FIFOOVER BIT(8) /* PCI FIFO Overread Attention Enable, R/W */ +#define B57XX_DMA_MODE_OVERLENGTH BIT(9) /* Local Memory Longer Than DMA Length, R/W */ +#define B57XX_DMA_MODE_SPLITTIMEOUT BIT(10) /* PCI-X Split Transaction Timeout Expired Attn, R/W */ +#define B57XX_DMA_MODE_STATUSTAGFIX BIT(29) /* Status Tag Fix, R/W for supported devices */ + +/* B57XX_REG_RISC_MODE */ +#define B57XX_REG_RISC_MODE_RESET BIT(0) /* Reset RISC, R/W */ +#define B57XX_REG_RISC_MODE_SINGLESTEP BIT(1) /* Single-Step RISC, R/W */ +#define B57XX_REG_RISC_MODE_DATAHALT BIT(2) /* Enable Page 0 Data Halt, R/W */ +#define B57XX_REG_RISC_MODE_INSTRHALT BIT(3) /* Enable Page 0 Instruction Halt, R/W */ +#define B57XX_REG_RISC_MODE_WRITEPBUF BIT(4) /* Enable Write Post Buffers, R/W */ +#define B57XX_REG_RISC_MODE_DATACACHE BIT(5) /* Enable Data Cache, R/W */ +#define B57XX_REG_RISC_MODE_ROMFAIL BIT(6) /* ROM Fail, R/W */ +#define B57XX_REG_RISC_MODE_WATCHDOG BIT(7) /* Enable Watchdog, R/W */ +#define B57XX_REG_RISC_MODE_INSTRCPREF BIT(8) /* Enable Instruction Cache prefetch, R/W */ +#define B57XX_REG_RISC_MODE_INSTRCFLUSH BIT(9) /* Flush Instruction Cache, R/W */ +#define B57XX_REG_RISC_MODE_HALT BIT(10) /* Halt RISC, R/W */ +#define B57XX_REG_RISC_MODE_INVLDDATA BIT(11) /* Enable Invalid Data access halt, R/W */ +#define B57XX_REG_RISC_MODE_INVLDINSTR BIT(12) /* Enable Invalid Instruction Fetch halt, R/W */ +#define B57XX_REG_RISC_MODE_MEMTRAPHALT BIT(13) /* Enable memory address trap halt, R/W */ +#define B57XX_REG_RISC_MODE_REGTRAPHALT BIT(14) /* Enable register address trap halt, R/W */ + +/* B57XX_DMA_COMPLETION */ +#define B57XX_DMA_COMPLETION_RESET BIT(0) /* Reset, R/W */ +#define B57XX_DMA_COMPLETION_ENABLE BIT(1) /* Enable, R/W */ + +/* B57XX_MODE_CTRL */ +#define B57XX_MODE_CTRL_UPDATEONCOAL BIT(0) /* Update on Coalescing Only, for supported dev. */ +#define B57XX_MODE_CTRL_BYTESWAPNF BIT(1) /* Byte Swap Non-frame Data, R/W */ +#define B57XX_MODE_CTRL_WORDSWAPNF BIT(2) /* Word Swap Non-frame Data, R/W */ +#define B57XX_MODE_CTRL_BYTESWAPDATA BIT(4) /* Byte Swap Data, R/W */ +#define B57XX_MODE_CTRL_WORDSWAPDATA BIT(5) /* Word Swap Data, R/W */ +#define B57XX_MODE_CTRL_NOFRAMECRACK BIT(9) /* No Frame Cracking, R/W */ +#define B57XX_MODE_CTRL_BADFRAMES BIT(11) /* Allow Bad Frames, R/W */ +#define B57XX_MODE_CTRL_NOINTONTX BIT(13) /* Don’t Interrupt on Sends, R/W */ +#define B57XX_MODE_CTRL_NOINTONRX BIT(14) /* Don’t Interrupt on Receives, R/W */ +#define B57XX_MODE_CTRL_FORCE32BITPCI BIT(15) /* Force 32-bit PCI, R/W */ +#define B57XX_MODE_CTRL_HOSTSTACKUP BIT(16) /* Host Stack Up, R/W */ +#define B57XX_MODE_CTRL_HOSTSENDBDS BIT(17) /* Host Send BDs, R/W */ +#define B57XX_MODE_CTRL_NOTXPSHCS BIT(20) /* Send No Pseudo-header Checksum, R/W */ +#define B57XX_MODE_CTRL_NVMWRITE BIT(21) /* NVRAM Write Enable, R/W for supported devices */ +#define B57XX_MODE_CTRL_NORXPSHCS BIT(23) /* Receive No Pseudoheader Checksum, R/W */ +#define B57XX_MODE_CTRL_INTTXRISCATTN BIT(24) /* Int. on TX RISC, R/W for supported devices */ +#define B57XX_MODE_CTRL_INTRXRISCATTN BIT(25) /* Int. on RX RISC, R/W for supported devices */ +#define B57XX_MODE_CTRL_INTMACATTN BIT(26) /* Interrupt on MAC Attention, R/W */ +#define B57XX_MODE_CTRL_INTDMAATTN BIT(27) /* Interrupt on DMA Attention, R/W */ +#define B57XX_MODE_CTRL_INTFLOWATTN BIT(28) /* Interrupt on Flow Attention, R/W */ +#define B57XX_MODE_CTRL_4XTXRINGS BIT(29) /* 4x NIC TX Rings, R/W for supported devices */ +#define B57XX_MODE_CTRL_MULTICASTRISC BIT(30) /* Route MC Frames to RISC, R/W for s. devices */ + +/* B57XX_MISC_CONFIG */ +#define B57XX_MISC_CONFIG_CLCKRESET BIT(0) /* CORE Clock Blocks Reset, R/W */ +#define B57XX_MISC_CONFIG_POVERRIDE BIT(26) /* Power_Down_Override, R/W for supported devices */ +#define B57XX_MISC_CONFIG_DGRPCIEB BIT(29) /* Disa_GRC_Reset_PCI-E, R/W for supported devices*/ + +/* B57XX_MISC_LOCAL_CTRL */ +#define B57XX_MISC_LOCAL_CTRL_INTSTATE BIT(0) /* Interrupt State, R/O */ +#define B57XX_MISC_LOCAL_CTRL_CLEARINT BIT(1) /* Clear Interrupt, W/O */ +#define B57XX_MISC_LOCAL_CTRL_SETINT BIT(2) /* Set Interrupt, W/O */ +#define B57XX_MISC_LOCAL_CTRL_INTATTN BIT(3) /* Interrupt on Attention, R/W */ +#define B57XX_MISC_LOCAL_CTRL_GPIOI3 BIT(5) /* GPIO 3 Input Enable, R/W for s. devices */ +#define B57XX_MISC_LOCAL_CTRL_GPIOO3 BIT(6) /* GPIO 3 Output Enable, R/W for s. devices */ +#define B57XX_MISC_LOCAL_CTRL_EXTMEM BIT(17) /* Enable External Memory, R/W for s. devices */ +#define B57XX_MISC_LOCAL_CTRL_SEEPROM BIT(24) /* Auto SEEPROM Access, R/W */ + +/* B57XX_RX_LIST_SELECT_MODE */ +#define B57XX_RX_LIST_SELECT_MODE_RESET BIT(0) /* Reset, R/W */ +#define B57XX_RX_LIST_SELECT_MODE_ENABLE BIT(1) /* Enable, R/W */ +#define B57XX_RX_LIST_SELECT_MODE_ATTN BIT(2) /* Attention Enable, R/W */ + +/* B57XX_SOFT_ARB */ +#define B57XX_SOFT_ARB_REQSET0 BIT(0) /* REQ_SET0, W/O */ +#define B57XX_SOFT_ARB_REQSET1 BIT(1) /* REQ_SET1, W/O */ +#define B57XX_SOFT_ARB_REQSET2 BIT(2) /* REQ_SET2, W/O */ +#define B57XX_SOFT_ARB_REQSET3 BIT(3) /* REQ_SET0, W/O */ +#define B57XX_SOFT_ARB_REQCLR0 BIT(4) /* REQ_CLR0, W/O */ +#define B57XX_SOFT_ARB_REQCLR1 BIT(5) /* REQ_CLR1, W/O */ +#define B57XX_SOFT_ARB_REQCLR2 BIT(6) /* REQ_CLR2, W/O */ +#define B57XX_SOFT_ARB_REQCLR3 BIT(7) /* REQ_CLR3, W/O */ +#define B57XX_SOFT_ARB_ARBWON0 BIT(8) /* ARB_WON0, R/O */ +#define B57XX_SOFT_ARB_ARBWON1 BIT(9) /* ARB_WON1, R/O */ +#define B57XX_SOFT_ARB_ARBWON2 BIT(10) /* ARB_WON2, R/O */ +#define B57XX_SOFT_ARB_ARBWON3 BIT(11) /* ARB_WON3, R/O */ +#define B57XX_SOFT_ARB_ARBWON3 BIT(11) /* ARB_WON3, R/O */ +#define B57XX_SOFT_ARB_REQ0 BIT(12) /* REQ0, R/O */ +#define B57XX_SOFT_ARB_REQ1 BIT(13) /* REQ1, R/O */ +#define B57XX_SOFT_ARB_REQ2 BIT(14) /* REQ2, R/O */ +#define B57XX_SOFT_ARB_REQ3 BIT(15) /* REQ3, R/O */ + +/* B57XX_STAT_CTRL */ +#define B57XX_STAT_CTRL_ENABLE BIT(0) /* Statistics Enable, R/W */ +#define B57XX_STAT_CTRL_FASTSTAT BIT(1) /* Faster Statistics Update, R/W for s. devices */ +#define B57XX_STAT_CTRL_CLEAR BIT(2) /* Statistics Clear, R/W */ +#define B57XX_STAT_CTRL_FORCEFLUSH BIT(3) /* Force Statistics Flush, R/W for supported devices */ +#define B57XX_STAT_CTRL_FORCEZERO BIT(4) /* Force Statistics Zero, R/W for supported devices */ + +/* B57XX_RX_DATA_COMPL_MODE */ +#define B57XX_RX_DATA_COMPL_MODE_RESET BIT(0) /* Reset, R/W */ +#define B57XX_RX_DATA_COMPL_MODE_ENABLE BIT(1) /* Enable, R/W */ +#define B57XX_RX_DATA_COMPL_MODE_ATTN BIT(2) /* Attention Enable, R/W */ + +/* B57XX_BD_MODE */ +#define B57XX_BD_MODE_RESET BIT(0) /* Reset, R/W */ +#define B57XX_BD_MODE_ENABLE BIT(1) /* Enable, R/W */ +#define B57XX_BD_MODE_ATTN BIT(2) /* Attention Enable, R/W */ + +/* B57XX_MBUF_CLUSTER_FREE */ +#define B57XX_MBUF_CLUSTER_FREE_RESET BIT(0) /* Reset, R/W */ +#define B57XX_MBUF_CLUSTER_FREE_ENABLE BIT(1) /* Enable, R/W */ +#define B57XX_MBUF_CLUSTER_FREE_ATTN BIT(2) /* Attention Enable, R/W */ + +/* B57XX_COAL_HOST_MODE */ +#define B57XX_COAL_HOST_MODE_RESET BIT(0) /* Reset, R/W */ +#define B57XX_COAL_HOST_MODE_ENABLE BIT(1) /* Enable, R/W */ +#define B57XX_COAL_HOST_MODE_ATTN BIT(2) /* Attention Enable, R/W */ +#define B57XX_COAL_HOST_MODE_COALNOW BIT(3) /* Coalesce Now, R/W */ +#define B57XX_COAL_HOST_MODE_STATUS_SZFULL (0b00 << 7) /* Full status block, R/W for s. dev. */ +#define B57XX_COAL_HOST_MODE_STATUS_SZ64 (0b01 << 7) /* 64 byte status block, R/W for s. dev. */ +#define B57XX_COAL_HOST_MODE_STATUS_SZ32 (0b10 << 7) /* 32 byte status block, R/W for s. dev. */ +#define B57XX_COAL_HOST_MODE_STATUS_SZUNDEF (0b11 << 7) /* Undefined size, R/W for supported dev. */ +#define B57XX_COAL_HOST_MODE_CLEARTICKRX BIT(9) /* Clear Ticks Mode on RX, R/W */ +#define B57XX_COAL_HOST_MODE_CLEARTICKTX BIT(10) /* Clear Ticks Mode on TX, R/W */ +#define B57XX_COAL_HOST_MODE_NOINTDMADFORCE BIT(11) /* No Interrupt on DMAD Force, R/W */ +#define B57XX_COAL_HOST_MODE_NOINTFORCEUPD BIT(12) /* No Interrupt on Force Update, R/W */ + +/* B57XX_MEM_ARB_MODE */ +#define B57XX_MEM_ARB_MODE_RESET BIT(0) /* Reset, R/W */ +#define B57XX_MEM_ARB_MODE_ENABLE BIT(1) /* Enable, R/W */ + +/* B57XX_MSI_MODE */ +#define B57XX_MSI_MODE_RESET BIT(0) /* Reset, R/W */ +#define B57XX_MSI_MODE_ENABLE BIT(1) /* Enable, R/W */ + +/* B57XX_TLP_CTRL */ +#define B57XX_TLP_CTRL_FIFOPROTECT BIT(25) /* Data FIFO Protect, R/W */ +#define B57XX_TLP_CTRL_INTMODEFIX BIT(29) /* Interrupt Mode Fix, R/W for supported devices */ + +/* PHY MII Registers */ +#define B57XX_MII_REG_CTRL 0x00 +#define B57XX_MII_REG_STATUS 0x01 +#define B57XX_MII_REG_PHY_ID1 0x02 +#define B57XX_MII_REG_PHY_ID2 0x03 +#define B57XX_MII_REG_AUTONEG_ADVERT 0x04 +#define B57XX_MII_REG_AUTONEG_PARTNER 0x05 +#define B57XX_MII_REG_AUX_CTRL 0x18 +#define B57XX_MII_REG_AUX_STATUS 0x19 +#define B57XX_MII_REG_INT_STATUS 0x1A +#define B57XX_MII_REG_INT_MASK 0x1B + +/* PHY Interrupts */ +#define B57XX_PHY_INT_CRC BIT(0) /* CRC Error */ +#define B57XX_PHY_INT_LINKSTATUS BIT(1) /* Link Status Change */ +#define B57XX_PHY_INT_LINKSPEED BIT(2) /* Link Speed Change */ +#define B57XX_PHY_INT_DUPLEXMODE BIT(3) /* Duplex Mode Change */ +#define B57XX_PHY_INT_LOCALCHANGE BIT(4) /* Local Receiver Status Change */ +#define B57XX_PHY_INT_REMOTECHANGE BIT(5) /* Remote Receiver Status Change */ +#define B57XX_PHY_INT_SCRAMBLERSYNC BIT(6) /* Scrambler Synchronization Error */ +#define B57XX_PHY_INT_UNSUPHCD BIT(7) /* Negotiated Unsupported HCD */ +#define B57XX_PHY_INT_NOHDC BIT(8) /* No HCD */ +#define B57XX_PHY_INT_HDCNOLINK BIT(9) /* HCD No Link */ +#define B57XX_PHY_INT_AUTONEGPAGERX BIT(10) /* Auto-negotiation Page Received */ +#define B57XX_PHY_INT_EXCEEDEDLOCNT BIT(11) /* Exceeded Low Counter Threshold */ +#define B57XX_PHY_INT_EXCEEDEDHICNT BIT(12) /* Exceeded High Counter Threshold */ +#define B57XX_PHY_INT_MDIXSTATUS BIT(13) /* MDIX Status Change */ +#define B57XX_PHY_INT_PAIRSWAP BIT(14) /* Illegal Pair Swap */ +#define B57XX_PHY_INT_SIGDETECT BIT(15) /* Signal Detect/Energy Detect Change */ + +/* PHY Auto-Negotiation Partner/Advertisement Ability */ +#define B57XX_PHY_AUTONEG_10TH BIT(5) /* 10BASE-T Half-Duplex Capability */ +#define B57XX_PHY_AUTONEG_10TF BIT(6) /* 10BASE-T Full-Duplex Capability */ +#define B57XX_PHY_AUTONEG_100TH BIT(7) /* 100BASE-TX Half-Duplex Capability */ +#define B57XX_PHY_AUTONEG_100TF BIT(8) /* 100BASE-TX Full-Duplex Capability */ +#define B57XX_PHY_AUTONEG_100T4 BIT(9) /* 100BASE-T4 Capability */ +#define B57XX_PHY_AUTONEG_PAUSE BIT(10) /* Pause Capable */ +#define B57XX_PHY_AUTONEG_ASYMPAUSE BIT(11) /* Asymmetric Pause */ +#define B57XX_PHY_AUTONEG_REMOTEFAULT BIT(13) /* Remote Fault */ +#define B57XX_PHY_AUTONEG_ACKNOWLEDGE BIT(14) /* Acknowledge */ +#define B57XX_PHY_AUTONEG_NEXTPAGE BIT(15) /* Next Page */ + +/* PHY MII Status */ +#define B57XX_PHY_MII_STATUS_EXTCAP BIT(0) /* Extended Capability */ +#define B57XX_PHY_MII_STATUS_JABBER BIT(1) /* Jabber Detect */ +#define B57XX_PHY_MII_STATUS_LINKSTATUS BIT(2) /* Link Status */ +#define B57XX_PHY_MII_STATUS_AUTONEGABILITY BIT(3) /* Auto-negotiation Ability */ +#define B57XX_PHY_MII_STATUS_REMOTEFAULT BIT(4) /* Remote Fault */ +#define B57XX_PHY_MII_STATUS_AUTONEGCOMPLETE BIT(5) /* Auto-negotiation Complete */ +#define B57XX_PHY_MII_STATUS_MGMTFRAMEPRESUP BIT(6) /* Management Frames Preamble Suppression */ +#define B57XX_PHY_MII_STATUS_EXTSTATUS BIT(8) /* Extended Status */ +#define B57XX_PHY_MII_STATUS_CAP100TH BIT(9) /* 100BASE-T2 Half-Duplex Capable */ +#define B57XX_PHY_MII_STATUS_CAP100TF BIT(10) /* 100BASE-T2 Full-Duplex Capable */ +#define B57XX_PHY_MII_STATUS_CAP10TH BIT(11) /* 10BASE-T Half-Duplex Capable */ +#define B57XX_PHY_MII_STATUS_CAP10TF BIT(12) /* 10BASE-T Full-Duplex Capable */ +#define B57XX_PHY_MII_STATUS_CAP100XH BIT(13) /* 100BASE-X Half-Duplex Capable */ +#define B57XX_PHY_MII_STATUS_CAP100XF BIT(14) /* 100BASE-X Full-Duplex Capable */ +#define B57XX_PHY_MII_STATUS_CAP100T4 BIT(15) /* 100BASE-T4 Capable */ + +/* PHY Aux Status */ +#define B57XX_PHY_AUX_STATUS_PAUSETXDIR BIT(0) /* Pause Resolution–TX Direction */ +#define B57XX_PHY_AUX_STATUS_PAUSERXDIR BIT(1) /* Pause Resolution–RX Direction */ +#define B57XX_PHY_AUX_STATUS_LINKSTATUS BIT(2) /* Link Status */ +#define B57XX_PHY_AUX_STATUS_PARTNERNP BIT(3) /* Link Partner NextPage Ability */ +#define B57XX_PHY_AUX_STATUS_PARTERAUTONEG BIT(4) /* Link Partner Autoneg Ability */ +#define B57XX_PHY_AUX_STATUS_ANPAGERX BIT(5) /* Auto-negotiation Page Received */ +#define B57XX_PHY_AUX_STATUS_REMOTEFAULT BIT(6) /* Remote Fault */ +#define B57XX_PHY_AUX_STATUS_PARALLELFAULT BIT(7) /* Parallel Detection Fault */ +#define B57XX_MASK_PHY_AUX_STATUS_MODE (0b111 << 8) /* Status mode */ +#define B57XX_PHY_AUX_STATUS_MODE_NONE (0b000 << 8) /* No highest common denominator */ +#define B57XX_PHY_AUX_STATUS_MODE_10TH (0b001 << 8) /* 10BASE-T half-duplex */ +#define B57XX_PHY_AUX_STATUS_MODE_10TF (0b010 << 8) /* 10BASE-T full-duplex */ +#define B57XX_PHY_AUX_STATUS_MODE_100TXH (0b011 << 8) /* 100BASE-TX half-duplex */ +#define B57XX_PHY_AUX_STATUS_MODE_100T4 (0b100 << 8) /* 100BASE-T4 */ +#define B57XX_PHY_AUX_STATUS_MODE_100TXF (0b101 << 8) /* 100BASE-TX full-duplex */ +#define B57XX_PHY_AUX_STATUS_MODE_1000TH (0b110 << 8) /* 1000BASE-T half-duplex */ +#define B57XX_PHY_AUX_STATUS_MODE_1000TF (0b111 << 8) /* 1000BASE-T full-duplex */ +#define B57XX_PHY_AUX_STATUS_AUTONEGNPW BIT(11) /* Auto-negotiation NextPage Wait */ +#define B57XX_PHY_AUX_STATUS_AUTONEG BIT(12) /* Auto-negotiation Ability Detect */ +#define B57XX_PHY_AUX_STATUS_AUTONEGACK BIT(13) /* Auto-negotiation Ack Detect */ +#define B57XX_PHY_AUX_STATUS_AUTONEGCOMPACK BIT(14) /* Auto-negotiation Complete Ack */ +#define B57XX_PHY_AUX_STATUS_AUTONEGCOMP BIT(15) /* Auto-negotiation Complete */ + +/* EOF */ diff --git a/drivers/network/dd/b57xx/hardware.c b/drivers/network/dd/b57xx/hardware.c index 64849dca8fcf6..c4142bb258252 100644 --- a/drivers/network/dd/b57xx/hardware.c +++ b/drivers/network/dd/b57xx/hardware.c @@ -2,473 +2,1581 @@ * PROJECT: ReactOS Broadcom NetXtreme Driver * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: Hardware specific functions - * COPYRIGHT: Copyright 2021 Scott Maday + * COPYRIGHT: Copyright 2021-2022 Scott Maday */ #include "nic.h" -#include "debug.h" +#define NDEBUG +#include -/* NIC FUNCTIONS **************************************************************/ +static const struct _B57XX_DEVICE +{ + USHORT DeviceID1; + USHORT DeviceID2; + USHORT DeviceID3; + USHORT SubsystemID; +} Devices[] = +{ + [B5700] = { 0x1644 }, + [B5701] = { 0x1645 }, + [B5702] = { 0x16A6, 0x1646, 0x16C6 }, + [B5703S] = { 0x16C7, 0x1647, 0x16A7, 0x000A }, + [B5703C] = { 0x16C7, 0x1647, 0x16A7 }, + [B5704C] = { 0x1648 }, + [B5704S] = { 0x16A8, 0x1649 }, + [B5705] = { 0x1653, 0x1654 }, + [B5705M] = { 0x165D, 0x165E }, + [B5788] = { 0x169C }, + [B5721] = { 0x1659 }, + [B5751] = { 0x1677 }, + [B5751M] = { 0x167D }, + [B5752] = { 0x1600 }, + [B5752M] = { 0x1601 }, + [B5714C] = { 0x1668 }, + [B5714S] = { 0x1669 }, + [B5715C] = { 0x1678 }, + [B5715S] = { 0x1679 }, + [B5722] = { 0x165A }, + [B5755] = { 0x167B }, + [B5755M] = { 0x1673 }, + [B5754] = { 0x167A }, + [B5754M] = { 0x1672 }, + [B5756M] = { 0x1674 }, + [B5757] = { 0x1670 }, + [B5786] = { 0x169A }, + [B5787] = { 0x169B }, + [B5787M] = { 0x1693 }, + [B5784M] = { 0x1698 }, + [B5764M] = { 0x1684 }, +}; + +/* NIC FUNCTIONS **********************************************************************************/ -NDIS_STATUS +BOOLEAN NTAPI -NICInitializeAdapterResources(IN PB57XX_ADAPTER Adapter, - IN PNDIS_RESOURCE_LIST ResourceList) +NICIsDevice(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG DeviceIDListLength, + _In_reads_(DeviceIDListLength) const B57XX_DEVICE_ID DeviceIDList[]) { - for (UINT n = 0; n < ResourceList->Count; n++) + for (UINT i = 0; i < DeviceIDListLength; i++) { - PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor = ResourceList->PartialDescriptors + n; + if (DeviceIDList[i] == Adapter->DeviceID) + { + return TRUE; + } + } + return FALSE; +} + - switch (ResourceDescriptor->Type) +_Check_return_ +NDIS_STATUS +NTAPI +NICConfigureAdapter(_In_ PB57XX_ADAPTER Adapter) +{ + UINT i; + ULONG AdditionalFrameSize = sizeof(ETH_HEADER) + 4; + ULONG Alignment = Adapter->PciState.CacheLineSize; + + ASSERT(Adapter->PciState.DeviceID != 0); + + for (i = 0; i < ARRAYSIZE(Devices); i++) + { + if ((Devices[i].DeviceID1 == Adapter->PciState.DeviceID || + Devices[i].DeviceID2 == Adapter->PciState.DeviceID || + Devices[i].DeviceID3 == Adapter->PciState.DeviceID) && + (Devices[i].SubsystemID == 0 || + Devices[i].SubsystemID == Adapter->PciState.SubSystemID)) { - case CmResourceTypePort: - ASSERT(Adapter->IoPortAddress == 0); - ASSERT(ResourceDescriptor->u.Port.Start.HighPart == 0); + Adapter->DeviceID = i; + break; + } + } + if (i == ARRAYSIZE(Devices)) + { + NDIS_MinDbgPrint("Could not identify device\n"); + return NDIS_STATUS_FAILURE; + } + + Adapter->B5705Plus = !NICISDEVICE(Adapter, B5700, B5701, B5702, B5703C, B5703S, B5704C, B5704S); + Adapter->B5721Plus = Adapter->B5705Plus && !NICISDEVICE(Adapter, B5705, B5705M, B5788); + Adapter->IsSerDes = NICISDEVICE(Adapter, B5703S, B5704S, B5714S, B5715S); + + if (Alignment % 8 != 0) + { + Alignment += 8 - (Alignment % 8); + } + + /* Standard receive producer ring */ + Adapter->MaxFrameSize = PAYLOAD_SIZE_STANDARD + AdditionalFrameSize; + + Adapter->StandardProducer.FrameBufferLength = Adapter->MaxFrameSize; + if (Adapter->StandardProducer.FrameBufferLength % Alignment != 0) + { + Adapter->StandardProducer.FrameBufferLength += Alignment - ( + Adapter->StandardProducer.FrameBufferLength % + Alignment); + } + Adapter->StandardProducer.Count = NICISDEVICE(Adapter, B5705) ? 512 : NUM_RX_BUFFER_DESCRIPTORS; + Adapter->StandardProducer.Index = Adapter->StandardProducer.Count - 1; + + /* Receive consumer rings */ + Adapter->ReturnConsumer[0].Count = NICISDEVICE(Adapter, B5705) ? + 512 : NUM_RX_RETURN_DESCRIPTORS; + + /* Send producer rings */ + Adapter->SendProducer[0].Count = NUM_TX_BUFFER_DESCRIPTORS; + + return NDIS_STATUS_SUCCESS; +} - Adapter->IoPortAddress = ResourceDescriptor->u.Port.Start.LowPart; - Adapter->IoPortLength = ResourceDescriptor->u.Port.Length; +_Check_return_ +NDIS_STATUS +NTAPI +NICPowerOn(_In_ PB57XX_ADAPTER Adapter) +{ + NDIS_STATUS Status; + ULONG Value; + UINT n; + + Adapter->HardwareStatus = NdisHardwareStatusNotReady; - NDIS_DbgPrint(MID_TRACE, ("I/O port range is %p to %p\n", - Adapter->IoPortAddress, - Adapter->IoPortAddress + Adapter->IoPortLength)); - break; - case CmResourceTypeInterrupt: - ASSERT(Adapter->InterruptVector == 0); - ASSERT(Adapter->InterruptLevel == 0); + /* Initialization Procedure step 1: Enable MAC memory space decode and bus mastering */ + B57XXEnableUShort(Adapter, + B57XX_REG_COMMAND, + &Value, + B57XX_COMMAND_MEMSPACE | B57XX_COMMAND_BUSMASTER); - Adapter->InterruptVector = ResourceDescriptor->u.Interrupt.Vector; - Adapter->InterruptLevel = ResourceDescriptor->u.Interrupt.Level; - Adapter->InterruptShared = (ResourceDescriptor->ShareDisposition == - CmResourceShareShared); - Adapter->InterruptFlags = ResourceDescriptor->Flags; + /* Initialization Procedure step 2: Disable interrupts */ + B57XXEnableULong(Adapter, B57XX_REG_MISC_HOST_CTRL, &Value, B57XX_MISC_HOST_CTRL_CINTA); + NICDisableInterrupts(Adapter); - NDIS_DbgPrint(MID_TRACE, ("IRQ vector is %d\n", Adapter->InterruptVector)); - break; - case CmResourceTypeMemory: - /* Internal registers and memories (including PHY) */ - if (ResourceDescriptor->u.Memory.Length == (128 * 1024)) - { - ASSERT(Adapter->IoAddress.LowPart == 0); - ASSERT(ResourceDescriptor->u.Port.Start.HighPart == 0); - - - Adapter->IoAddress.QuadPart = ResourceDescriptor->u.Memory.Start.QuadPart; - Adapter->IoLength = ResourceDescriptor->u.Memory.Length; - NDIS_DbgPrint(MID_TRACE, ("Memory range is %I64x to %I64x\n", - Adapter->IoAddress.QuadPart, - Adapter->IoAddress.QuadPart + Adapter->IoLength)); - } - break; + /* Initialization Procedure step 3 should be done already (Save select PCI registers) */ - default: - NDIS_MinDbgPrint("Unrecognized resource type: 0x%x\n", ResourceDescriptor->Type); + /* Initialization Procedure step 4: Acquire the NVRAM lock */ + if (!NICISDEVICE(Adapter, B5700, B5701)) + { + B57XXEnableULong(Adapter, B57XX_REG_SOFT_ARB, &Value, B57XX_SOFT_ARB_REQSET1); + for (n = 0; n < MAX_ATTEMPTS; n++) + { + NdisStallExecution(1); + B57XXReadULong(Adapter, B57XX_REG_SOFT_ARB, &Value); + if (Value & B57XX_SOFT_ARB_ARBWON1) + { break; + } + } + if (n == MAX_ATTEMPTS) + { + NDIS_MinDbgPrint("Could not aquire device arbitration register\n"); + return NDIS_STATUS_DEVICE_FAILED; } } - - if (Adapter->IoAddress.QuadPart == 0 || - Adapter->IoPortAddress == 0 || - Adapter->InterruptVector == 0) + + /* Initialization Procedure step 5: Prepare the chip for writing T3_MAGIC_NUMBER */ + B57XXEnableULong(Adapter, B57XX_REG_MEM_ARB_MODE, &Value, B57XX_MEM_ARB_MODE_ENABLE); + + B57XXEnableULong(Adapter, + B57XX_REG_MISC_HOST_CTRL, + &Value, + B57XX_MISC_HOST_CTRL_INDIRECTACCESS | + B57XX_MISC_HOST_CTRL_CLOCKCTRL | + B57XX_ENDIAN_SWAP(B57XX_ENDIAN_BYTESWAP, + B57XX_MISC_HOST_CTRL_ENDIANBYTESWAP, + B57XX_ENDIAN_WORDSWAP, + B57XX_MISC_HOST_CTRL_ENDIANWORDSWAP)); + B57XXEnableULong(Adapter, + B57XX_REG_MODE_CTRL, + &Value, + B57XX_ENDIAN_SWAP(B57XX_ENDIAN_BYTESWAP_NFDATA, + B57XX_MODE_CTRL_BYTESWAPNF, + B57XX_ENDIAN_WORDSWAP_NFDATA, + B57XX_MODE_CTRL_WORDSWAPNF)); + + /* Initialization Procedure steps 6+ */ + B57XXWriteMemoryULong(Adapter, B57XX_ADDR_FW_DRV_STATE_MAILBOX, B57XX_CONST_DRV_STATE_START); + + Status = NICSoftReset(Adapter); + if (Status != NDIS_STATUS_SUCCESS) { - NDIS_MinDbgPrint("Adapter didn't receive enough resources\n"); - return NDIS_STATUS_RESOURCES; + return Status; } + return NDIS_STATUS_SUCCESS; } -BOOLEAN -NTAPI -NICRecognizeHardware(IN PB57XX_ADAPTER Adapter) -{ - NDIS_MinDbgPrint("NICRecognizeHardware\n"); - - return FALSE; -} - +_Check_return_ NDIS_STATUS NTAPI -NICAllocateIoResources(IN PB57XX_ADAPTER Adapter) +NICSoftReset(_In_ PB57XX_ADAPTER Adapter) { NDIS_STATUS Status; - //ULONG AllocationSize; - - NDIS_MinDbgPrint("NICAllocateIoResources\n"); + ULONG Value; + B57XX_RING_CONTROL_BLOCK RCBValue; + UINT n; + + Adapter->HardwareStatus = NdisHardwareStatusReset; - Status = NdisMRegisterIoPortRange((PVOID*)&Adapter->IoPort, - Adapter->MiniportAdapterHandle, - Adapter->IoPortAddress, - Adapter->IoPortLength); - if (Status != NDIS_STATUS_SUCCESS) + /* Initialization Procedure step 6: Prepare firmware for reset */ + B57XXWriteMemoryULong(Adapter, B57XX_ADDR_FW_MAILBOX, B57XX_CONST_T3_MAGIC_NUMBER); + + if (NICISDEVICE(Adapter, B5752)) { - NDIS_MinDbgPrint("Unable to register IO port range (0x%x)\n", Status); - return NDIS_STATUS_RESOURCES; + B57XXWriteULong(Adapter, B57XX_REG_FASTBOOT_COUNTER, 0); } - Status = NdisMMapIoSpace((PVOID*)&Adapter->IoBase, - Adapter->MiniportAdapterHandle, - Adapter->IoAddress, - Adapter->IoLength); - - /*NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, - sizeof(EB57XXTRANSMIT_DESCRIPTOR) * NUM_TRANSMIT_DESCRIPTORS, - FALSE, - (PVOID*)&Adapter->TransmitDescriptors, - &Adapter->TransmitDescriptorsPa); - if (Adapter->TransmitDescriptors == NULL) + /* Initialization Procedure step 7: Reset the core clocks */ + if (NICISDEVICE(Adapter, B5751, B5751M, B5721, B5752, B5752M)) { - NDIS_MinDbgPrint("Unable to allocate transmit descriptors\n")); - return NDIS_STATUS_RESOURCES; + B57XXEnableULong(Adapter, + B57XX_REG_PCI_CLOCK, + &Value, + B57XX_PCI_CLOCK_ALTCLOCKFINAL | B57XX_PCI_CLOCK_ALTCLOCK); } - - for (UINT n = 0; n < NUM_TRANSMIT_DESCRIPTORS; ++n) + + B57XXReadULong(Adapter, B57XX_REG_MISC_CONFIG, &Value); + Value |= B57XX_MISC_CONFIG_CLCKRESET; + if (Adapter->B5705Plus) { - PEB57XXTRANSMIT_DESCRIPTOR Descriptor = Adapter->TransmitDescriptors + n; - Descriptor->Address = 0; - Descriptor->Length = 0; + Value |= B57XX_MISC_CONFIG_POVERRIDE; } - - NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, - sizeof(EB57XXRECEIVE_DESCRIPTOR) * NUM_RECEIVE_DESCRIPTORS, - FALSE, - (PVOID*)&Adapter->ReceiveDescriptors, - &Adapter->ReceiveDescriptorsPa); - if (Adapter->ReceiveDescriptors == NULL) + if (Adapter->B5721Plus) { - NDIS_MinDbgPrint("Unable to allocate receive descriptors\n"); - return NDIS_STATUS_RESOURCES; + Value |= B57XX_MISC_CONFIG_DGRPCIEB; } + B57XXWriteULong(Adapter, B57XX_REG_MISC_CONFIG, Value); + + /* Initialization Procedure step 8: Wait for core-clock reset to complete. */ + /* We can't poll the core-clock reset bit to de-assert, + since the local memory interface is disabled by the reset. */ + NdisStallExecution(90000); + B57XXReadPciConfigULong(Adapter, B57XX_REG_COMMAND, &Value); + NdisStallExecution(10000); + + /* Initialization Procedure step 9: Disable interrupts */ + NICDisableInterrupts(Adapter); - AllocationSize = RcvBufAllocationSize(Adapter->ReceiveBufferType); - ASSERT(Adapter->ReceiveBufferEntrySize == 0 || - Adapter->ReceiveBufferEntrySize == AllocationSize); - Adapter->ReceiveBufferEntrySize = AllocationSize; - - NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, - Adapter->ReceiveBufferEntrySize * NUM_RECEIVE_DESCRIPTORS, - FALSE, - (PVOID*)&Adapter->ReceiveBuffer, - &Adapter->ReceiveBufferPa); - - if (Adapter->ReceiveBuffer == NULL) + /* Initialization Procedure step 10: Enable MAC memory space decode and bus mastering */ + NdisWriteRegisterUshort((PUSHORT)(Adapter->IoBase + B57XX_REG_COMMAND), + Adapter->PciState.Command | + B57XX_COMMAND_MEMSPACE | + B57XX_COMMAND_BUSMASTER); + + /* Initialization Procedure step 11: Disable PCI-X Relaxed Ordering */ + NdisReadRegisterUshort((PUSHORT)(Adapter->IoBase + B57XX_REG_PCIX_COMMAND), &Value); + Value &= ~B57XX_PCIX_COMMAND_RELAXEDORDER; + NdisWriteRegisterUshort((PUSHORT)(Adapter->IoBase + B57XX_REG_PCIX_COMMAND), Value); + + /* Initialization Procedure step 12: Enable the MAC memory arbiter */ + B57XXEnableULong(Adapter, B57XX_REG_MEM_ARB_MODE, &Value, B57XX_MEM_ARB_MODE_ENABLE); + + /* Initialization Procedure step 13: Enable External Memory */ + if (NICISDEVICE(Adapter, B5700)) { - NDIS_MinDbgPrint("Unable to allocate receive buffer\n"); - return NDIS_STATUS_RESOURCES; + // TODO B5700 External memory config + // If you have one of these, please let me know } - - for (UINT n = 0; n < NUM_RECEIVE_DESCRIPTORS; ++n) + + /* Initialization Procedure step 14: Initialize the Miscellaneous Host Control register */ + B57XXEnableULong(Adapter, + B57XX_REG_MISC_HOST_CTRL, + &Value, + B57XX_MISC_HOST_CTRL_INDIRECTACCESS | + B57XX_MISC_HOST_CTRL_PCISTATE | + B57XX_MISC_HOST_CTRL_CLOCKCTRL | + B57XX_ENDIAN_SWAP(B57XX_ENDIAN_BYTESWAP, + B57XX_MISC_HOST_CTRL_ENDIANBYTESWAP, + B57XX_ENDIAN_WORDSWAP, + B57XX_MISC_HOST_CTRL_ENDIANWORDSWAP)); + + /* Initialization Procedure step 15-16: Initialize the General Mode Control register */ + B57XXEnableULong(Adapter, + B57XX_REG_MODE_CTRL, + &Value, + B57XX_ENDIAN_SWAP(B57XX_ENDIAN_BYTESWAP_DATA, + B57XX_MODE_CTRL_BYTESWAPDATA, + B57XX_ENDIAN_WORDSWAP_DATA, + B57XX_MODE_CTRL_WORDSWAPDATA) | + B57XX_ENDIAN_SWAP(B57XX_ENDIAN_BYTESWAP_NFDATA, + B57XX_MODE_CTRL_BYTESWAPNF, + B57XX_ENDIAN_WORDSWAP_NFDATA, + B57XX_MODE_CTRL_WORDSWAPNF)); + + /* Initialization Procedure step 17: Poll for bootcode completion */ + for (n = 0; n < MAX_ATTEMPTS; n++) { - PEB57XXRECEIVE_DESCRIPTOR Descriptor = Adapter->ReceiveDescriptors + n; - - RtlZeroMemory(Descriptor, sizeof(*Descriptor)); - Descriptor->Address = Adapter->ReceiveBufferPa.QuadPart + n * - Adapter->ReceiveBufferEntrySize; + B57XXReadMemoryULong(Adapter, B57XX_ADDR_FW_MAILBOX, &Value); + if (Value == ~B57XX_CONST_T3_MAGIC_NUMBER) + { + break; + } + NdisStallExecution(100); + } + if (n == MAX_ATTEMPTS) + { + NDIS_MinDbgPrint("Device did not recover reset (Firmware mailbox: 0x%x)\n", Value); + return NDIS_STATUS_FAILURE; + } + Adapter->HardwareStatus = NdisHardwareStatusInitializing; + NDIS_MinDbgPrint("Device is back from reset (%u)\n", n); + + /* Initialization Procedure step 18: Initialize the Ethernet MAC Mode register */ + if (Adapter->IsSerDes) + { + B57XXWriteRegister(Adapter, B57XX_REG_ETH_MAC_MODE, B57XX_ETH_MAC_MODE_PORT_TBI); + } + else + { + B57XXWriteRegister(Adapter, B57XX_REG_ETH_MAC_MODE, B57XX_ETH_MAC_MODE_PORT_GMI); + } + + /* Initialization Procedure step 19-20: Enable the PCIe bug fix & Enable data FIFO protection */ + if (Adapter->B5721Plus) + { + B57XXEnableRegister(Adapter, + B57XX_REG_TLP_CTRL, + &Value, + B57XX_TLP_CTRL_FIFOPROTECT | B57XX_TLP_CTRL_INTMODEFIX); + } + + /* Initialization Procedure step 21: Enable the hardware fixes */ + if (Adapter->B5705Plus) + { + B57XXEnableRegister(Adapter, + B57XX_REG_HW_FIX, + &Value, + B57XX_HW_FIX_HWFIX1 | B57XX_HW_FIX_HWFIX3 | B57XX_HW_FIX_HWFIX4); + } + + /* Initialization Procedure step 22: Enable Tagged Status Mode */ + B57XXEnableRegister(Adapter, + B57XX_REG_MISC_HOST_CTRL, + &Value, + B57XX_MISC_HOST_CTRL_TAGGEDSTATUS); + + /* Initialization Procedure step 23: Restore select PCI registers */ + NdisWriteRegisterUchar((PUCHAR)(Adapter->IoBase + B57XX_REG_CACHE_LINE_SIZE), + Adapter->PciState.CacheLineSize); + NdisWriteRegisterUshort((PUSHORT)(Adapter->IoBase + B57XX_REG_SUBSY_VENDORID), + Adapter->PciState.SubVendorID); + + /* Initialization Procedure steps 24-25: Clear the MAC/driver statistics (not applicable) */ + + /* Initialization Procedure steps 26: Clear the MAC/driver status (done earlier) */ + + /* Initialization Procedure step 27: Set the default PCI Command Encoding R/W Transactions */ + B57XXReadRegister(Adapter, B57XX_REG_PCI_STATE, &Value); + if (NICISDEVICE(Adapter, B5700, B5701)) + { + Value = (Value & B57XX_PCI_STATE_BUSMODE) ? 0x761B000F : 0x763F000F; + } + else if (NICISDEVICE(Adapter, B5702)) + { + Value = 0x763F000F; + } + else if (NICISDEVICE(Adapter, B5703C, B5703S, B5704C, B5704S)) + { + if (Value & B57XX_PCI_STATE_BUSMODE) + { + Value = (Value & B57XX_PCI_STATE_HIGHSPEED) ? 0x769F4000 : 0x769F0000; + } + Value = 0x763F0000; + } + else if (NICISDEVICE(Adapter, B5705, B5705M, B5788)) + { + Value = 0x763F0000; + } + else if (NICISDEVICE(Adapter, B5714C, B5714S, B5715C, B5715S)) + { + Value = 0x76144000; + } + else + { + NdisReadRegisterUshort((PUSHORT)(Adapter->IoBase + B57XX_REG_DEVICE_CTRL), &Value); + Value = (Value & (0b111 << 5)) ? 0x76380000 : 0x76180000; + } + B57XXWriteRegister(Adapter, B57XX_REG_DMA_CTRL, Value); + + /* Initialization Procedure step 28 done in step 15-16 (Set DMA byte swapping) */ + + /* Initialization Procedure step 29-31: Host-based send rings, Ready RX traffic, Checksums */ + B57XXEnableRegister(Adapter, + B57XX_REG_MODE_CTRL, + &Value, + B57XX_MODE_CTRL_INTMACATTN | + B57XX_MODE_CTRL_HOSTSENDBDS | + B57XX_MODE_CTRL_HOSTSTACKUP | + B57XX_MODE_CTRL_NOTXPSHCS); + + /* Initialization Procedure step 32: Configure timer */ + B57XXReadRegister(Adapter, B57XX_REG_MISC_CONFIG, &Value); + Value &= ~(0x7F << 1); + Value |= (65 << 1); // Increment every 1 uS + B57XXWriteRegister(Adapter, B57XX_REG_MISC_CONFIG, Value); + + /* Initialization Procedure step 33: MAC local memory pool */ + if (NICISDEVICE(Adapter, B5700)) + { + B57XXEnableRegister(Adapter, + B57XX_REG_MISC_LOCAL_CTRL, + &Value, + B57XX_MISC_LOCAL_CTRL_EXTMEM); + B57XXWriteRegister(Adapter, B57XX_REG_MBUF_POOL_BASE, 0x20000); + B57XXWriteRegister(Adapter, B57XX_REG_MBUF_POOL_LENGTH, 0); // FIXME for B5700 + } + if (NICISDEVICE(Adapter, B5701, B5702, B5703C, B5703S)) + { + B57XXWriteRegister(Adapter, B57XX_REG_MBUF_POOL_BASE, 0x8000); + B57XXWriteRegister(Adapter, B57XX_REG_MBUF_POOL_LENGTH, 0x18000); + } + else if (NICISDEVICE(Adapter, B5704C, B5704S)) + { + B57XXWriteRegister(Adapter, B57XX_REG_MBUF_POOL_BASE, 0x10000); + B57XXWriteRegister(Adapter, B57XX_REG_MBUF_POOL_LENGTH, 0x10000); + } + + /* Initialization Procedure step 34: MAC DMA resource pool */ + if (!Adapter->B5705Plus) + { + B57XXWriteRegister(Adapter, B57XX_REG_DMA_DESC_POOL_BASE, 0x2000); + B57XXWriteRegister(Adapter, B57XX_REG_DMA_DESC_POOL_LENGTH, 0x2000); + } + + /* Initialization Procedure step 35: MAC memory pool watermarks (Standard frames) */ + if (!Adapter->B5705Plus) + { + B57XXWriteRegister(Adapter, B57XX_REG_MBUF_POOL_DMA_LO_WM, 0x50); + B57XXWriteRegister(Adapter, B57XX_REG_MBUF_POOL_RX_LO_WM, 0x20); + B57XXWriteRegister(Adapter, B57XX_REG_MBUF_POOL_HI_WM, 0x60); + } + else + { + B57XXWriteRegister(Adapter, B57XX_REG_MBUF_POOL_DMA_LO_WM, 0x00); + B57XXWriteRegister(Adapter, B57XX_REG_MBUF_POOL_RX_LO_WM, 0x10); + B57XXWriteRegister(Adapter, B57XX_REG_MBUF_POOL_HI_WM, 0x60); + } + + /* Initialization Procedure step 36: MAC DMA pool watermarks */ + B57XXWriteRegister(Adapter, B57XX_REG_DMA_DESC_POOL_LO_WM, 5); + B57XXWriteRegister(Adapter, B57XX_REG_DMA_DESC_POOL_HI_WM, 10); + + /* Initialization Procedure step 37: Configure flow control behavior */ + B57XXWriteRegister(Adapter, B57XX_REG_ETH_RX_LOW_WM_MAX, 2); + + /* Initialization Procedure step 38-39: Enable the buffer manager */ + B57XXEnableRegister(Adapter, + B57XX_REG_BUF_MAN_MODE, + &Value, + B57XX_BUF_MAN_MODE_ENABLE | B57XX_BUF_MAN_MODE_ATTN); + + for (n = 0; n < MAX_ATTEMPTS; n++) + { + NdisStallExecution(10); + B57XXReadRegister(Adapter, B57XX_REG_BUF_MAN_MODE, &Value); + if (Value & B57XX_BUF_MAN_MODE_ENABLE) + { + break; + } + } + if (n == MAX_ATTEMPTS) + { + NDIS_MinDbgPrint("Unable to start NIC buffer manager\n"); + return NDIS_STATUS_FAILURE; + } + + /* Initialization Procedure step 40: Enable internal hardware queues */ + B57XXWriteRegister(Adapter, B57XX_REG_FTQ_RESET, 0xFFFFFFFF); + B57XXWriteRegister(Adapter, B57XX_REG_FTQ_RESET, 0x00000000); + + /* Initialization Procedure step 41: Standard Receive Buffer Ring (Internal memory) */ + Adapter->StandardProducer.RingControlBlock.MaxLength = !Adapter->B5705Plus ? + Adapter->MaxFrameSize : + Adapter->StandardProducer.Count; + Adapter->StandardProducer.RingControlBlock.NICRingAddress = B57XX_ADDR_RECEIVE_STD_RINGS; + + B57XXWriteRegister(Adapter, + B57XX_REG_STD_RXP_RING_HOST_HI, + Adapter->StandardProducer.RingControlBlock.HostRingAddress.HighPart); + B57XXWriteRegister(Adapter, + B57XX_REG_STD_RXP_RING_HOST_LO, + Adapter->StandardProducer.RingControlBlock.HostRingAddress.LowPart); + B57XXWriteRegister(Adapter, + B57XX_REG_STD_RXP_RING_ATTR, + Adapter->StandardProducer.RingControlBlock.MaxLength << 16); + B57XXWriteRegister(Adapter, + B57XX_REG_STD_RXP_RING_NIC, + Adapter->StandardProducer.RingControlBlock.NICRingAddress); + B57XXWriteMailbox(Adapter, B57XX_MBOX_STD_RXP_RING_INDEX, 0); + + /* Initialization Procedure step 42: Jumbo Receive Buffer Ring (disable) */ + if (!Adapter->B5705Plus) + { + Adapter->JumboProducer.RingControlBlock.Flags = B57XX_RCB_FLAG_RING_DISABLED; + Adapter->JumboProducer.RingControlBlock.NICRingAddress = B57XX_ADDR_RECEIVE_JUMBO_RINGS; + + B57XXWriteRegister(Adapter, + B57XX_REG_JUMB_RXP_RING_ATTR, + Adapter->JumboProducer.RingControlBlock.Flags); + B57XXWriteRegister(Adapter, + B57XX_REG_JUMB_RXP_RING_NIC, + Adapter->JumboProducer.RingControlBlock.NICRingAddress); + B57XXWriteMailbox(Adapter, B57XX_MBOX_JUMBO_RXP_RING_INDEX, 0); + } + + /* Initialization Procedure step 43: Mini Receive Buffer Ring (disable) */ + if (NICISDEVICE(Adapter, B5700)) + { + Adapter->MiniProducer.RingControlBlock.Flags = B57XX_RCB_FLAG_RING_DISABLED; + Adapter->MiniProducer.RingControlBlock.NICRingAddress = B57XX_ADDR_RECEIVE_MINI_RINGS; + + B57XXWriteRegister(Adapter, + B57XX_REG_MINI_RXP_RING_ATTR, + Adapter->MiniProducer.RingControlBlock.Flags); + B57XXWriteRegister(Adapter, + B57XX_REG_MINI_RXP_RING_NIC, + Adapter->MiniProducer.RingControlBlock.NICRingAddress); + B57XXWriteMailbox(Adapter, B57XX_MBOX_MINI_RXP_RING_INDEX, 0); + } + + /* Initialization Procedure step 44: Set the BD Ring replenish thresholds for RX Rings */ + B57XXWriteRegister(Adapter, B57XX_REG_STD_RX_RING_REPL, 25); + + /* Initialization Procedure step 45-47: Initialize send rings & Disable unused send rings */ + Adapter->SendProducer[0].RingControlBlock.MaxLength = Adapter->SendProducer[0].Count; + Adapter->SendProducer[0].RingControlBlock.NICRingAddress = B57XX_ADDR_SEND_RINGS; + B57XXWriteMemoryRCB(Adapter, B57XX_ADDR_SEND_RCBS, &Adapter->SendProducer[0].RingControlBlock); + B57XXWriteMailbox(Adapter, B57XX_MBOX_TXP_HOST_RING_INDEX1, 0); + B57XXWriteMailbox(Adapter, B57XX_MBOX_TXP_NIC_RING_INDEX1, 0); + + if (!Adapter->B5705Plus) + { + NdisZeroMemory(&RCBValue, sizeof(B57XX_RING_CONTROL_BLOCK)); + RCBValue.Flags = B57XX_RCB_FLAG_RING_DISABLED; + for (n = 1; n < 4; n++) + { + B57XXWriteMemoryRCB(Adapter, + B57XX_ADDR_SEND_RCBS + n * sizeof(B57XX_RING_CONTROL_BLOCK), + &RCBValue); + B57XXWriteMailbox(Adapter, B57XX_MBOX_TXP_HOST_RING_INDEX1 + n * 8, 0); + } } - return NDIS_STATUS_SUCCESS;*/ + /* Initialization Procedure step 48-50: Initialize Receive Return Rings & Disable unused ones */ + Adapter->ReturnConsumer[0].RingControlBlock.MaxLength = Adapter->ReturnConsumer[0].Count; + Adapter->ReturnConsumer[0].RingControlBlock.NICRingAddress = 0; + B57XXWriteMemoryRCB(Adapter, + B57XX_ADDR_RECEIVE_RETURN_RCBS, + &Adapter->ReturnConsumer[0].RingControlBlock); + B57XXWriteMailbox(Adapter, B57XX_MBOX_RXC_RET_RING_INDEX1, 0); + + if (!Adapter->B5705Plus) + { + NdisZeroMemory(&RCBValue, sizeof(B57XX_RING_CONTROL_BLOCK)); + RCBValue.Flags = B57XX_RCB_FLAG_RING_DISABLED; + for (n = 1; n < 16; n++) + { + B57XXWriteMemoryRCB(Adapter, + B57XX_ADDR_RECEIVE_RETURN_RCBS + + n * sizeof(B57XX_RING_CONTROL_BLOCK), + &RCBValue); + B57XXWriteMailbox(Adapter, B57XX_MBOX_RXC_RET_RING_INDEX1 + n * 8, 0); + } + } + + /* Initialization Procedure step 51: Receive Producer Ring mailbox */ + B57XXWriteMailbox(Adapter, B57XX_MBOX_STD_RXP_RING_INDEX, Adapter->StandardProducer.Index); + + /* Initialization Procedure step 52: Configure the MAC unicast address */ + NICUpdateMACAddresses(Adapter); + + /* Initialization Procedure step 53: Configure random backoff seed for transmit */ + Value = (Adapter->MACAddresses[0][0] + + Adapter->MACAddresses[0][1] + + Adapter->MACAddresses[0][2] + + Adapter->MACAddresses[0][3] + + Adapter->MACAddresses[0][4] + + Adapter->MACAddresses[0][5]) & 0x3FF; + B57XXWriteRegister(Adapter, B57XX_REG_ETH_TX_RND_BACKOFF, Value); + + /* Initialization Procedure step 54: Configure the Message Transfer Unit MTU size */ + // We need to include VLAN tags for the MTU + B57XXWriteRegister(Adapter, B57XX_REG_ETH_RX_MTU_SIZE, Adapter->MaxFrameSize + 4); + + /* Initialization Procedure step 55: Configure IPG for transmit */ + B57XXWriteRegister(Adapter, B57XX_REG_ETH_TX_LENGTH, 0x2620); + + /* Initialization Procedure step 56: Configure default RX return ring for non-matched packets */ + B57XXWriteRegister(Adapter, B57XX_REG_ETH_RX_RULES_CONFIG, (1 << 3)); + + /* Initialization Procedure step 57: Configure the number of Receive Lists */ + B57XXWriteRegister(Adapter, B57XX_REG_RX_LIST_PLACE_CONFIG, 0x181); + + /* Initialization Procedure step 58: Receive List Placement Statistics mask */ + B57XXWriteRegister(Adapter, B57XX_REG_RX_LIST_STAT_MASK, 0xFFFFFF); + + /* Initialization Procedure step 59: Enable RX statistics */ + B57XXEnableRegister(Adapter, + B57XX_REG_RX_LIST_STAT_CTRL, + &Value, + B57XX_STAT_CTRL_ENABLE); + + /* Initialization Procedure step 60: Enable the Send Data Initiator mask */ + B57XXWriteRegister(Adapter, B57XX_REG_TX_DATA_STAT_MASK, 0xFFFFFF); + + /* Initialization Procedure step 61: Enable TX statistics */ + B57XXEnableRegister(Adapter, + B57XX_REG_TX_DATA_STAT_CTRL, + &Value, + B57XX_STAT_CTRL_ENABLE | B57XX_STAT_CTRL_FASTSTAT); + + /* Initialization Procedure step 62: Disable the host coalescing eng */ + B57XXWriteRegister(Adapter, B57XX_REG_COAL_HOST_MODE, 0x0000); + + /* Initialization Procedure step 63: Poll 20 ms for the host coalescing engine to stop */ + for (n = 0; n < MAX_ATTEMPTS; n++) + { + NdisStallExecution(20); + B57XXReadRegister(Adapter, B57XX_REG_COAL_HOST_MODE, &Value); + if (Value == 0x0000) + { + break; + } + } + if (n == MAX_ATTEMPTS) + { + NDIS_MinDbgPrint("Unable to start NIC buffer manager\n"); + return NDIS_STATUS_FAILURE; + } + + /* Initialization Procedure step 64: Configure the host coalescing tick count */ + B57XXWriteRegister(Adapter, B57XX_REG_COAL_RX_TICKS, 300); + B57XXWriteRegister(Adapter, B57XX_REG_COAL_TX_TICKS, 150); + + /* Initialization Procedure step 65: Configure the host coalescing BD count */ + B57XXWriteRegister(Adapter, B57XX_REG_COAL_RX_MAX_BD, 20); + B57XXWriteRegister(Adapter, B57XX_REG_COAL_TX_MAX_BD, 10); + + /* Initialization Procedure step 66: Configure during interrupt tick counter */ + B57XXWriteRegister(Adapter, B57XX_REG_COAL_RX_INT_TICKS, 0); + B57XXWriteRegister(Adapter, B57XX_REG_COAL_TX_INT_TICKS, 0); + + /* Initialization Procedure step 67: Configure the max-coalesced frames during int. counter */ + B57XXWriteRegister(Adapter, B57XX_REG_COAL_RX_MAX_INT_BD, 0); + B57XXWriteRegister(Adapter, B57XX_REG_COAL_TX_MAX_INT_BD, 0); + + /* Initialization Procedure step 68: Initialize host status block address */ + B57XXWriteRegister(Adapter, + B57XX_REG_STATUS_BLCK_HOST_ADDR, + Adapter->Status.HostAddress.HighPart); + B57XXWriteRegister(Adapter, + B57XX_REG_STATUS_BLCK_HOST_ADDR + 4, + Adapter->Status.HostAddress.LowPart); + + /* Initialization Procedure step 69-71: Initialize statistics block */ + if (!Adapter->B5705Plus) + { + B57XXWriteRegister(Adapter, + B57XX_REG_STAT_HOST_ADDR, + Adapter->Statistics.HostAddress.HighPart); + B57XXWriteRegister(Adapter, + B57XX_REG_STAT_HOST_ADDR + 4, + Adapter->Statistics.HostAddress.LowPart); + B57XXWriteRegister(Adapter, B57XX_REG_STAT_TICKS, 1000000); + B57XXWriteRegister(Adapter, B57XX_REG_STAT_BASE_ADDR, B57XX_ADDR_STAT_BLCK); + } + + /* Initialization Procedure step 72: Configure the status block address in NIC local memory */ + if (!Adapter->B5705Plus) + { + B57XXWriteRegister(Adapter, B57XX_REG_STATUS_BLCK_BASE_ADDR, B57XX_ADDR_STATUS_BLCK); + } + + /* Initialization Procedure step 73: Enable the host coalescing engine */ + B57XXEnableRegister(Adapter, + B57XX_REG_COAL_HOST_MODE, + &Value, + B57XX_COAL_HOST_MODE_ENABLE | + B57XX_COAL_HOST_MODE_ATTN); + + /* Initialization Procedure step 74: Enable the receive BD completion functional block */ + B57XXEnableRegister(Adapter, + B57XX_REG_RX_BD_COMPL_MODE, + &Value, + B57XX_BD_MODE_ENABLE | B57XX_BD_MODE_ATTN); + + /* Initialization Procedure step 75: Enable the receive list placement functional block */ + B57XXEnableRegister(Adapter, + B57XX_REG_RX_LIST_PLACE_MODE, + &Value, + B57XX_RX_LIST_PLACE_MODE_ENABLE); + + /* Initialization Procedure step 76: Enable the receive list selector functional block */ + B57XXEnableRegister(Adapter, + B57XX_REG_RX_LIST_SELECT_MODE, + &Value, + B57XX_RX_LIST_SELECT_MODE_ENABLE | B57XX_RX_LIST_SELECT_MODE_ATTN); + + /* Initialization Procedure step 77-78: Enable DMA engines & Enable and clear statistics */ + B57XXEnableRegister(Adapter, + B57XX_REG_ETH_MAC_MODE, + &Value, + B57XX_ETH_MAC_MODE_TXDMA | + B57XX_ETH_MAC_MODE_RXDMA | + B57XX_ETH_MAC_MODE_RXFHDDMA | + B57XX_ETH_MAC_MODE_RXSTATCLEAR | + B57XX_ETH_MAC_MODE_RXSTATENABLE | + B57XX_ETH_MAC_MODE_TXSTATCLEAR | + B57XX_ETH_MAC_MODE_TXSTATENABLE); + NdisStallExecution(40); + + /* Initialization Procedure step 79: Configure General Miscellaneous Local Control */ + Value = B57XX_MISC_LOCAL_CTRL_INTATTN | B57XX_MISC_LOCAL_CTRL_SEEPROM; + if (NICISDEVICE(Adapter, B5752)) + { + Value |= B57XX_MISC_LOCAL_CTRL_GPIOO3; + } + B57XXWriteRegister(Adapter, B57XX_REG_MISC_LOCAL_CTRL, Value); + NdisStallExecution(100); + + /* Initialization Procedure step 80: Write a value of zero to the Interrupt Mailbox 0 */ + B57XXWriteMailbox(Adapter, B57XX_MBOX_INT_MAILBOX0, 0); + + /* Initialization Procedure step 81: Enable DMA completion functional block */ + if (!Adapter->B5705Plus) + { + B57XXEnableRegister(Adapter, B57XX_REG_DMA_COMPLETION, &Value, B57XX_DMA_COMPLETION_ENABLE); + } + + /* Initialization Procedure step 82: Configure the Write DMA Mode register */ + B57XXEnableRegister(Adapter, + B57XX_REG_DMA_WRITE_MODE, + &Value, + B57XX_DMA_MODE_ENABLE | + B57XX_DMA_MODE_TARGETABORT | + B57XX_DMA_MODE_MASTERABORT | + B57XX_DMA_MODE_PARITYERROR | + B57XX_DMA_MODE_HOSTADDROF | + B57XX_DMA_MODE_FIFOOR | + B57XX_DMA_MODE_FIFOUR | + B57XX_DMA_MODE_FIFOOVER | + B57XX_DMA_MODE_OVERLENGTH | + B57XX_DMA_MODE_STATUSTAGFIX); + NdisStallExecution(40); + + /* Initialization Procedure step 83: Configure the Read DMA Mode register */ + B57XXEnableRegister(Adapter, + B57XX_REG_DMA_READ_MODE, + &Value, + B57XX_DMA_MODE_ENABLE | + B57XX_DMA_MODE_TARGETABORT | + B57XX_DMA_MODE_MASTERABORT | + B57XX_DMA_MODE_PARITYERROR | + B57XX_DMA_MODE_HOSTADDROF | + B57XX_DMA_MODE_FIFOOR | + B57XX_DMA_MODE_FIFOUR | + B57XX_DMA_MODE_FIFOOVER | + B57XX_DMA_MODE_OVERLENGTH); + NdisStallExecution(40); + + /* Initialization Procedure step 84: Enable the receive data completion functional block */ + B57XXEnableRegister(Adapter, + B57XX_REG_RX_DATA_COMPL_MODE, + &Value, + B57XX_RX_DATA_COMPL_MODE_ENABLE | B57XX_RX_DATA_COMPL_MODE_ATTN); + + /* Initialization Procedure step 85: Enable the Mbuf cluster free functional block */ + if (!Adapter->B5705Plus) + { + B57XXEnableRegister(Adapter, + B57XX_REG_MBUF_CLUSTER_FREE, + &Value, + B57XX_MBUF_CLUSTER_FREE_ENABLE); + } - return NDIS_STATUS_FAILURE; + /* Initialization Procedure step 86: Enable the send data completion functional block */ + B57XXEnableRegister(Adapter, B57XX_REG_TX_COMPL_MODE, &Value, B57XX_TX_COMPL_MODE_ENABLE); + + /* Initialization Procedure step 87: Enable the send BD completion functional block */ + B57XXEnableRegister(Adapter, + B57XX_REG_TX_BD_COMPL_MODE, + &Value, + B57XX_BD_MODE_ENABLE | B57XX_BD_MODE_ATTN); + + /* Initialization Procedure step 88: Enable the Receive BD Initiator Functional Block */ + B57XXEnableRegister(Adapter, + B57XX_REG_RX_BD_MODE, + &Value, + B57XX_BD_MODE_ENABLE | B57XX_BD_MODE_ATTN); + + /* Initialization Procedure step 89: Enable the receive data & BD initiator functional block */ + B57XXEnableRegister(Adapter, + B57XX_REG_RX_DATA_BD_MODE, + &Value, + B57XX_RX_DATA_BD_MODE_ENABLE | B57XX_RX_DATA_BD_MODE_ILLEGALSZ); + + /* Initialization Procedure step 90: Enable the send data initiator functional block */ + B57XXEnableRegister(Adapter, B57XX_REG_TX_DATA_MODE, &Value, B57XX_TX_DATA_MODE_ENABLE); + + /* Initialization Procedure step 91: Enable the send BD initiator functional block */ + B57XXEnableRegister(Adapter, + B57XX_REG_TX_INITIATOR_MODE, + &Value, + B57XX_BD_MODE_ENABLE | B57XX_BD_MODE_ATTN); + + /* Initialization Procedure step 92: Enable the send BD selector functional block */ + B57XXEnableRegister(Adapter, + B57XX_REG_TX_RING_SELECTOR_MODE, + &Value, + B57XX_BD_MODE_ENABLE | B57XX_BD_MODE_ATTN); + + /* Initialization Procedure step 93 not applicable: Download firmware */ + + /* Initialization Procedure step 94: Enable the transmit MAC */ + B57XXWriteRegister(Adapter, + B57XX_REG_ETH_TX_MODE, + B57XX_ETH_TX_MODE_ENABLE | B57XX_ETH_TX_MODE_LOCKUPFIX); + NdisStallExecution(100); + + /* Initialization Procedure step 95: Enable the receive MAC */ + B57XXWriteRegister(Adapter, B57XX_REG_ETH_RX_MODE, B57XX_ETH_RX_MODE_ENABLE); + NdisStallExecution(10); + + /* Initialization Procedure step 96: Disable auto-polling on management */ + B57XXWriteRegister(Adapter, B57XX_REG_ETH_MI_MODE, 0xC0000); + + /* Initialization Procedure step 97: Configure D0 power state in PMSCR */ + B57XXEnableUShort(Adapter, B57XX_REG_POWER_MANAGEMENT, &Value, B57XX_POWER_MANAGEMENT_STATE_D0); + + /* Initialization Procedure step 98: Program Hardware to control LEDs */ + B57XXWriteRegister(Adapter, B57XX_REG_ETH_LED, 0); + + /* Initialization Procedure step 99-100: Setup the physical layer & MAC functional blocks */ + B57XXWriteRegister(Adapter, B57XX_REG_ETH_MI_STATUS, B57XX_ETH_MI_STATUS_LINK); + Status = NICSetupPHY(Adapter); + if (Status != NDIS_STATUS_SUCCESS) + { + return Status; + } + + /* Initialization Procedure step 101: Setup multicast filters */ + NICUpdateMulticastList(Adapter); + NICApplyPacketFilter(Adapter); + + /* Initialization Procedure step 102: Enable interrupts (done later) */ + B57XXDisableRegister(Adapter, B57XX_REG_MSI_MODE, &Value, B57XX_MSI_MODE_ENABLE); + + Adapter->HardwareStatus = NdisHardwareStatusReady; + + return NDIS_STATUS_SUCCESS; } NDIS_STATUS NTAPI -NICRegisterInterrupts(IN PB57XX_ADAPTER Adapter) +NICSetupPHY(_In_ PB57XX_ADAPTER Adapter) { - NDIS_STATUS Status; - - NDIS_MinDbgPrint("NICRegisterInterrupts\n"); - - Status = NdisMRegisterInterrupt(&Adapter->Interrupt, - Adapter->MiniportAdapterHandle, - Adapter->InterruptVector, - Adapter->InterruptLevel, - TRUE, // We always want ISR calls - Adapter->InterruptShared, - (Adapter->InterruptFlags & CM_RESOURCE_INTERRUPT_LATCHED) ? - NdisInterruptLatched : NdisInterruptLevelSensitive); - - if (Status == NDIS_STATUS_SUCCESS) + /* PHY Initialization Procedure step 1: Disable link events */ + B57XXWriteRegister(Adapter, B57XX_REG_ETH_MAC_EVENT, 0x00); + + /* PHY Initialization Procedure step 2: Clear link attentions */ + B57XXClearMACAttentions(Adapter); + + /* PHY Initialization Procedure step 3: Disable Autopolling mode */ + B57XXWriteRegister(Adapter, B57XX_REG_ETH_MI_MODE, 0xC0000); + + /* PHY Initialization Procedure step 4: Wait for the Auto Poll disable step to complete */ + NdisStallExecution(40); + + /* PHY Initialization Procedure step 5: Disable WOL mode */ + B57XXWritePHY(Adapter, B57XX_MII_REG_AUX_CTRL, 0x02); + + /* PHY Initialization Procedure step 6: Errata for the physical layer component */ + + /* PHY Initialization Procedure step 8: Configure the PHY interrupt mask */ + B57XXWritePHY(Adapter, B57XX_MII_REG_INT_MASK, ~B57XX_PHY_INT_LINKSTATUS); + + /* PHY Initialization Procedure step 7-16 (not 8): Link status update */ + if (NICUpdateLinkStatus(Adapter) == NDIS_STATUS_MEDIA_CONNECT) { - Adapter->InterruptRegistered = TRUE; + NDIS_MinDbgPrint("Link connected\n"); } - - return Status; + + /* PHY Initialization Procedure step 17: Enable port polling */ + //B57XXEnableRegister(Adapter, B57XX_REG_ETH_MI_MODE, &Value, B57XX_ETH_MI_MODE_PORTPOLLING); + + /* PHY Initialization Procedure step 18: Enable link attentions */ + B57XXWriteRegister(Adapter, + B57XX_REG_ETH_MAC_EVENT, + B57XX_ETH_MAC_EVENT_LINKSTATE | B57XX_ETH_MAC_EVENT_MIINT); + + return NDIS_STATUS_SUCCESS; } NDIS_STATUS NTAPI -NICUnregisterInterrupts(IN PB57XX_ADAPTER Adapter) +NICUpdateLinkStatus(_In_ PB57XX_ADAPTER Adapter) { - NDIS_MinDbgPrint("NICUnregisterInterrupts\n"); - - if (Adapter->InterruptRegistered) + ULONG Value; + USHORT Value16; + + B57XXClearMACAttentions(Adapter); + + /* PHY Initialization Procedure step 7: Acknowledge outstanding interrupts */ + B57XXReadAndClearPHYInterrupts(Adapter, &Value16); + + /* PHY Initialization Procedure step 9: Configure the Three LINK LED Mode bit (optional) */ + + /* PHY Initialization Procedure step 10: Determine link status */ + B57XXReadPHY(Adapter, B57XX_MII_REG_STATUS, &Value16); + B57XXReadPHY(Adapter, B57XX_MII_REG_STATUS, &Value16); + + /* PHY Initialization Procedure step 11-12: Determine speed and duplex operation & store */ + NdisStallExecution(20000); + B57XXReadPHY(Adapter, B57XX_MII_REG_AUX_STATUS, &Value16); + Adapter->LinkStatus = Value16; + if (!(Value16 & B57XX_PHY_AUX_STATUS_LINKSTATUS)) + { + NDIS_MinDbgPrint("Link disconnected (0x%x)\n", Value16); + + B57XXReadPHY(Adapter, B57XX_MII_REG_AUTONEG_ADVERT, &Value16); + Value16 &= ~B57XX_PHY_AUTONEG_PAUSE; + B57XXWritePHY(Adapter, B57XX_MII_REG_AUTONEG_ADVERT, Value16); + + B57XXDisableRegister(Adapter, B57XX_REG_ETH_TX_MODE, &Value, B57XX_ETH_TX_MODE_FLOWCTRL); + B57XXDisableRegister(Adapter, B57XX_REG_ETH_RX_MODE, &Value, B57XX_ETH_RX_MODE_FLOWCTRL); + + B57XXClearMACAttentions(Adapter); + + return NDIS_STATUS_MEDIA_DISCONNECT; + } + + /* PHY Initialization Procedure step 13: Enable Flow Control */ + B57XXReadPHY(Adapter, B57XX_MII_REG_AUTONEG_ADVERT, &Value16); + Value16 |= B57XX_PHY_AUTONEG_PAUSE; + B57XXWritePHY(Adapter, B57XX_MII_REG_AUTONEG_ADVERT, Value16); + NICSetupFlowControl(Adapter); + + /* PHY Initialization Procedure step 14-16: Configure MAC port mode, duplex, & polarity */ + B57XXReadRegister(Adapter, B57XX_REG_ETH_MAC_MODE, &Value); + Value &= ~(B57XX_ETH_MAC_MODE_HALFDUPLEX | B57XX_MASK_ETH_MAC_MODE_PORT); + switch (Adapter->LinkStatus & B57XX_MASK_PHY_AUX_STATUS_MODE) { - NdisMDeregisterInterrupt(&Adapter->Interrupt); - Adapter->InterruptRegistered = FALSE; + case B57XX_PHY_AUX_STATUS_MODE_10TH: + Value |= B57XX_ETH_MAC_MODE_HALFDUPLEX; + NDIS_MinDbgPrint("Half duplex\n"); + case B57XX_PHY_AUX_STATUS_MODE_10TF: + Value |= B57XX_ETH_MAC_MODE_PORT_MII; + NDIS_MinDbgPrint("10BASE-T (MII)\n"); + break; + case B57XX_PHY_AUX_STATUS_MODE_100TXH: + case B57XX_PHY_AUX_STATUS_MODE_100T4: + Value |= B57XX_ETH_MAC_MODE_HALFDUPLEX; + NDIS_MinDbgPrint("Half duplex\n"); + case B57XX_PHY_AUX_STATUS_MODE_100TXF: + Value |= B57XX_ETH_MAC_MODE_PORT_MII; + NDIS_MinDbgPrint("100BASE-T (MII)\n"); + break; + case B57XX_PHY_AUX_STATUS_MODE_1000TH: + Value |= B57XX_ETH_MAC_MODE_HALFDUPLEX; + NDIS_MinDbgPrint("Half duplex\n"); + case B57XX_PHY_AUX_STATUS_MODE_1000TF: + Value |= B57XX_ETH_MAC_MODE_PORT_GMI; + NDIS_MinDbgPrint("1000BASE-T (GMI)\n"); + break; + default: + Value |= B57XX_ETH_MAC_MODE_PORT_NONE; } + B57XXWriteRegister(Adapter, B57XX_REG_ETH_MAC_MODE, Value); + + B57XXClearMACAttentions(Adapter); + return NDIS_STATUS_MEDIA_CONNECT; +} - return NDIS_STATUS_SUCCESS; +VOID +NTAPI +NICSetupFlowControl(_In_ PB57XX_ADAPTER Adapter) +{ + ULONG Value; + USHORT AutonegLocal; + USHORT AutonegRemote; + BOOLEAN FlowControlTX = FALSE; + BOOLEAN FlowControlRX = FALSE; + + if (!((Adapter->LinkStatus & B57XX_PHY_AUX_STATUS_MODE_10TF) || + (Adapter->LinkStatus & B57XX_PHY_AUX_STATUS_MODE_100TXF) || + (Adapter->LinkStatus & B57XX_PHY_AUX_STATUS_MODE_1000TF))) + { + NDIS_MinDbgPrint("Flow control only available in full-duplex mode.\n"); + goto Finish; + } + + if (!(Adapter->LinkStatus & B57XX_PHY_AUX_STATUS_AUTONEGCOMP)) + { + NDIS_MinDbgPrint("Autonegotiation not complete, cannot configure Flow control\n"); + goto Finish; + } + + B57XXReadPHY(Adapter, B57XX_MII_REG_AUTONEG_ADVERT, &AutonegLocal); + B57XXReadPHY(Adapter, B57XX_MII_REG_AUTONEG_PARTNER, &AutonegRemote); + + if ((AutonegLocal & B57XX_PHY_AUTONEG_PAUSE) && (AutonegLocal & B57XX_PHY_AUTONEG_ASYMPAUSE)) + { + FlowControlTX = (AutonegRemote & B57XX_PHY_AUTONEG_PAUSE) ? TRUE : FALSE; + FlowControlRX = (AutonegRemote & B57XX_PHY_AUTONEG_ASYMPAUSE) ? TRUE : FALSE; + } + else if (AutonegLocal & B57XX_PHY_AUTONEG_PAUSE) + { + FlowControlTX = FlowControlRX = (AutonegRemote & B57XX_PHY_AUTONEG_PAUSE) ? TRUE : FALSE; + } + else if (AutonegLocal & B57XX_PHY_AUTONEG_ASYMPAUSE) + { + FlowControlTX = (AutonegRemote & B57XX_PHY_AUTONEG_PAUSE) ? TRUE : FALSE; + } + +Finish: + B57XXReadRegister(Adapter, B57XX_REG_ETH_TX_MODE, &Value); + if (FlowControlTX) + { + Value |= B57XX_ETH_TX_MODE_FLOWCTRL; + } + else + { + Value &= ~B57XX_ETH_TX_MODE_FLOWCTRL; + } + B57XXWriteRegister(Adapter, B57XX_REG_ETH_TX_MODE, Value); + + B57XXReadRegister(Adapter, B57XX_REG_ETH_RX_MODE, &Value); + if (FlowControlRX) + { + Value |= B57XX_ETH_RX_MODE_FLOWCTRL; + } + else + { + Value &= ~B57XX_ETH_RX_MODE_FLOWCTRL; + } + B57XXWriteRegister(Adapter, B57XX_REG_ETH_RX_MODE, Value); } NDIS_STATUS NTAPI -NICReleaseIoResources(IN PB57XX_ADAPTER Adapter) +NICShutdown(_In_ PB57XX_ADAPTER Adapter) { - NDIS_MinDbgPrint("NICReleaseIoResources\n"); - - /*if (Adapter->ReceiveDescriptors != NULL) + ULONG Value; + + if (Adapter->HardwareStatus != NdisHardwareStatusReady) { - // Disassociate our shared buffer before freeing it to avoid NIC-induced memory corruption - if (Adapter->IoBase) - { - B57XXWriteUlong(Adapter, B57XX_REG_RDH, 0); - B57XXWriteUlong(Adapter, B57XX_REG_RDT, 0); - } - - NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, - sizeof(B57XX_RECEIVE_DESCRIPTOR) * NUM_RECEIVE_DESCRIPTORS, - FALSE, - Adapter->ReceiveDescriptors, - Adapter->ReceiveDescriptorsPa); - - Adapter->ReceiveDescriptors = NULL; + return NDIS_STATUS_FAILURE; } - - if (Adapter->ReceiveBuffer != NULL) + Adapter->HardwareStatus = NdisHardwareStatusClosing; + + /* Receive path shutdown sequence. */ + B57XXDisableRegister(Adapter, B57XX_REG_ETH_RX_MODE, &Value, B57XX_ETH_RX_MODE_ENABLE); + B57XXDisableRegister(Adapter, B57XX_REG_RX_BD_MODE, &Value, B57XX_BD_MODE_ENABLE); + B57XXDisableRegister(Adapter, + B57XX_REG_RX_LIST_PLACE_MODE, + &Value, + B57XX_RX_LIST_PLACE_MODE_ENABLE); + if (!Adapter->B5705Plus) { - NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, - Adapter->ReceiveBufferEntrySize * NUM_RECEIVE_DESCRIPTORS, - FALSE, - Adapter->ReceiveBuffer, - Adapter->ReceiveBufferPa); - - Adapter->ReceiveBuffer = NULL; - Adapter->ReceiveBufferEntrySize = 0; + B57XXDisableRegister(Adapter, + B57XX_REG_RX_LIST_SELECT_MODE, + &Value, + B57XX_RX_LIST_SELECT_MODE_ENABLE); } - - - if (Adapter->TransmitDescriptors != NULL) + B57XXDisableRegister(Adapter, B57XX_REG_RX_DATA_BD_MODE, &Value, B57XX_RX_DATA_BD_MODE_ENABLE); + B57XXDisableRegister(Adapter, + B57XX_REG_RX_DATA_COMPL_MODE, + &Value, + B57XX_RX_DATA_COMPL_MODE_ENABLE); + B57XXDisableRegister(Adapter, B57XX_REG_RX_BD_COMPL_MODE, &Value, B57XX_BD_MODE_ENABLE); + + /* Transmit path shutdown sequence. */ + B57XXDisableRegister(Adapter, B57XX_REG_TX_RING_SELECTOR_MODE, &Value, B57XX_BD_MODE_ENABLE); + B57XXDisableRegister(Adapter, B57XX_REG_TX_INITIATOR_MODE, &Value, B57XX_BD_MODE_ENABLE); + B57XXDisableRegister(Adapter, B57XX_REG_TX_DATA_MODE, &Value, B57XX_TX_DATA_MODE_ENABLE); + B57XXDisableRegister(Adapter, B57XX_REG_DMA_READ_MODE, &Value, B57XX_DMA_MODE_ENABLE); + B57XXDisableRegister(Adapter, B57XX_REG_TX_COMPL_MODE, &Value, B57XX_TX_COMPL_MODE_ENABLE); + if (!Adapter->B5705Plus) { - // Disassociate our shared buffer before freeing it to avoid NIC-induced memory corruption - if (Adapter->IoBase) - { - B57XXWriteUlong(Adapter, B57XX_REG_TDH, 0); - B57XXWriteUlong(Adapter, B57XX_REG_TDT, 0); - } - - NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, - sizeof(B57XX_TRANSMIT_DESCRIPTOR) * NUM_TRANSMIT_DESCRIPTORS, - FALSE, - Adapter->TransmitDescriptors, - Adapter->TransmitDescriptorsPa); - - Adapter->TransmitDescriptors = NULL; - }*/ - - if (Adapter->IoPort) + B57XXDisableRegister(Adapter, + B57XX_REG_DMA_COMPLETION, + &Value, + B57XX_DMA_COMPLETION_ENABLE); + } + B57XXDisableRegister(Adapter, B57XX_REG_TX_BD_COMPL_MODE, &Value, B57XX_BD_MODE_ENABLE); + B57XXDisableRegister(Adapter, B57XX_REG_ETH_MAC_MODE, &Value, B57XX_ETH_MAC_MODE_TXDMA); + B57XXDisableRegister(Adapter, B57XX_REG_ETH_TX_MODE, &Value, B57XX_ETH_TX_MODE_ENABLE); + + /* Memory related state machines shutdown. */ + B57XXDisableRegister(Adapter, B57XX_REG_COAL_HOST_MODE, &Value, B57XX_COAL_HOST_MODE_ENABLE); + B57XXDisableRegister(Adapter, B57XX_REG_DMA_WRITE_MODE, &Value, B57XX_DMA_MODE_ENABLE); + if (!Adapter->B5705Plus) { - NdisMDeregisterIoPortRange(Adapter->MiniportAdapterHandle, - Adapter->IoPortAddress, - Adapter->IoPortLength, - Adapter->IoPort); + B57XXDisableRegister(Adapter, + B57XX_REG_MBUF_CLUSTER_FREE, + &Value, + B57XX_MBUF_CLUSTER_FREE_ENABLE); } - - if (Adapter->IoBase) + B57XXWriteRegister(Adapter, B57XX_REG_FTQ_RESET, 0xFFFFFFFF); + B57XXWriteRegister(Adapter, B57XX_REG_FTQ_RESET, 0x00000000); + if (!Adapter->B5705Plus) { - NdisMUnmapIoSpace(Adapter->MiniportAdapterHandle, Adapter->IoBase, Adapter->IoLength); + B57XXDisableRegister(Adapter, B57XX_REG_BUF_MAN_MODE, &Value, B57XX_BUF_MAN_MODE_ENABLE); + B57XXDisableRegister(Adapter, B57XX_REG_MEM_ARB_MODE, &Value, B57XX_MEM_ARB_MODE_ENABLE); } - + return NDIS_STATUS_SUCCESS; } -NDIS_STATUS +VOID NTAPI -NICPowerOn(IN PB57XX_ADAPTER Adapter) +NICUpdateMACAddresses(_In_ PB57XX_ADAPTER Adapter) { - NDIS_MinDbgPrint("NICPowerOn\n"); + ULONG Value; + + B57XXReadRegister(Adapter, B57XX_REG_ETH_MAC_ADDR1_HI, &Value); + Adapter->MACAddresses[0][0] = (Value >> 8) & 0xFF; + Adapter->MACAddresses[0][1] = (Value >> 0) & 0xFF; + + B57XXReadRegister(Adapter, B57XX_REG_ETH_MAC_ADDR1_LO, &Value); + Adapter->MACAddresses[0][2] = (Value >> 24) & 0xFF; + Adapter->MACAddresses[0][3] = (Value >> 16) & 0xFF; + Adapter->MACAddresses[0][4] = (Value >> 8) & 0xFF; + Adapter->MACAddresses[0][5] = (Value >> 0) & 0xFF; + + NDIS_MinDbgPrint("MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", + Adapter->MACAddresses[0][0], + Adapter->MACAddresses[0][1], + Adapter->MACAddresses[0][2], + Adapter->MACAddresses[0][3], + Adapter->MACAddresses[0][4], + Adapter->MACAddresses[0][5]); +} - NDIS_STATUS Status = NICSoftReset(Adapter); - if (Status != NDIS_STATUS_SUCCESS) +NDIS_STATUS +NTAPI +NICUpdateMulticastList(_In_ PB57XX_ADAPTER Adapter) +{ + ULONG Value; + ULONG RegIndex; + ULONG BitPos; + + B57XXWriteRegister(Adapter, B57XX_REG_ETH_MAC_HASH + 0, 0); + B57XXWriteRegister(Adapter, B57XX_REG_ETH_MAC_HASH + 4, 0); + B57XXWriteRegister(Adapter, B57XX_REG_ETH_MAC_HASH + 8, 0); + B57XXWriteRegister(Adapter, B57XX_REG_ETH_MAC_HASH + 12, 0); + + for (UINT i = 0; i < Adapter->MulticastListSize; i++) { - return Status; + BitPos = B57XXComputeInverseCrc32(Adapter->MulticastList[i], IEEE_802_ADDR_LENGTH) & 0x7F; + RegIndex = (BitPos & 0x60) >> 5; + BitPos &= 0x1F; + + ASSERT(RegIndex < 4); + + B57XXEnableRegister(Adapter, B57XX_REG_ETH_MAC_HASH + 4 * RegIndex, &Value, (1 << BitPos)); } - + return NDIS_STATUS_SUCCESS; } NDIS_STATUS NTAPI -NICSoftReset(IN PB57XX_ADAPTER Adapter) +NICApplyPacketFilter(_In_ PB57XX_ADAPTER Adapter) { - //ULONG Value; - NDIS_MinDbgPrint("NICSoftReset\n"); - - NICDisableInterrupts(Adapter); - // TODO Write and read to device registers - - for (ULONG ResetAttempts = 0; ResetAttempts < MAX_RESET_ATTEMPTS; ResetAttempts++) + ULONG Value; + + B57XXReadRegister(Adapter, B57XX_REG_ETH_RX_MODE, &Value); + Value &= ~(B57XX_ETH_RX_MODE_PROMISCUOUS | B57XX_ETH_RX_MODE_FILTBROAD); + if (Adapter->PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) { - NdisStallExecution(1); - /*B57XXReadUlong(Adapter, ???, &Value); - if (!(Value & B57XX_CTRL_RST)) - { - NDIS_MinDbgPrint("Device is back (%u)\n", ResetAttempts); - - NICDisableInterrupts(Adapter); - // Clear out interrupts (the register is cleared upon read) - // TODO Write and read to device registers - - return NDIS_STATUS_SUCCESS; - }*/ + Value |= B57XX_ETH_RX_MODE_PROMISCUOUS; } - - NDIS_MinDbgPrint("Unable to recover device"); - return NDIS_STATUS_FAILURE; + if (!(Adapter->PacketFilter & NDIS_PACKET_TYPE_BROADCAST)) + { + Value |= B57XX_ETH_RX_MODE_FILTBROAD; + } + B57XXWriteRegister(Adapter, B57XX_REG_ETH_RX_MODE, Value); + + if (Adapter->PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST) + { + B57XXWriteRegister(Adapter, B57XX_REG_ETH_MAC_HASH + 0, 0xFFFFFFFF); + B57XXWriteRegister(Adapter, B57XX_REG_ETH_MAC_HASH + 4, 0xFFFFFFFF); + B57XXWriteRegister(Adapter, B57XX_REG_ETH_MAC_HASH + 8, 0xFFFFFFFF); + B57XXWriteRegister(Adapter, B57XX_REG_ETH_MAC_HASH + 12, 0xFFFFFFFF); + } + else + { + NICUpdateMulticastList(Adapter); + } + + return NDIS_STATUS_SUCCESS; } +_Check_return_ NDIS_STATUS NTAPI -NICEnableTxRx(IN PB57XX_ADAPTER Adapter) +NICTransmitPacket(_In_ PB57XX_ADAPTER Adapter, + _In_ PHYSICAL_ADDRESS PhysicalAddress, + _In_ ULONG Length, + _In_ USHORT Flags) { - NDIS_MinDbgPrint("NICEnableTxRx\n"); + ULONG Index = Adapter->SendProducer[0].ProducerIndex; + + if (Adapter->SendProducer[0].RingFull == TRUE) + { + return NDIS_STATUS_RESOURCES; + } + + Adapter->SendProducer[0].pRing[Index].Length = Length; + Adapter->SendProducer[0].pRing[Index].Flags = Flags; + B57XXConvertAddress(&Adapter->SendProducer[0].pRing[Index].HostAddress, &PhysicalAddress); + + Index = (Index + 1) % Adapter->SendProducer[0].Count; + Adapter->SendProducer[0].ProducerIndex = Index; + B57XXWriteMailbox(Adapter, B57XX_MBOX_TXP_HOST_RING_INDEX1, Index); + + if (Index == Adapter->SendProducer[0].ConsumerIndex) + { + NDIS_MinDbgPrint("Send ring is full\n"); + Adapter->SendProducer[0].RingFull = TRUE; + } - // TODO Write and read to device registers + return NDIS_STATUS_SUCCESS; +} - return NDIS_STATUS_FAILURE; +VOID +NTAPI +NICEnableInterrupts(_In_ PB57XX_ADAPTER Adapter) +{ + ULONG Value; + + B57XXReadULong(Adapter, B57XX_REG_MISC_HOST_CTRL, &Value); + Value &= ~B57XX_MISC_HOST_CTRL_MASKINTOUT; + B57XXWriteULong(Adapter, B57XX_REG_MISC_HOST_CTRL, Value); } -NDIS_STATUS +VOID NTAPI -NICDisableTxRx(IN PB57XX_ADAPTER Adapter) +NICDisableInterrupts(_In_ PB57XX_ADAPTER Adapter) { - NDIS_MinDbgPrint("NICDisableTxRx\n"); + ULONG Value; + + B57XXEnableULong(Adapter, B57XX_REG_MISC_HOST_CTRL, &Value, B57XX_MISC_HOST_CTRL_MASKINTOUT); +} - // TODO Write and read to device registers +VOID +NTAPI +NICInterruptAcknowledge(_In_ PB57XX_ADAPTER Adapter) +{ + ULONG Value; + + B57XXWriteMailbox(Adapter, B57XX_MBOX_INT_MAILBOX0, 1); + B57XXEnableRegister(Adapter, B57XX_REG_MISC_LOCAL_CTRL, &Value, B57XX_MISC_LOCAL_CTRL_CLEARINT); +} - return NDIS_STATUS_FAILURE; +BOOLEAN +NTAPI +NICInterruptCheckAvailability(_In_ PB57XX_ADAPTER Adapter) +{ + ULONG Value; + + B57XXReadULong(Adapter, B57XX_MBOX_INT_MAILBOX0 + 4, &Value); + + return Adapter->Status.pBlock->Status & B57XX_SB_UPDATED; } -NDIS_STATUS +VOID NTAPI -NICGetPermanentMacAddress(IN PB57XX_ADAPTER Adapter, - OUT PUCHAR MacAddress) +NICInterruptSignalComplete(_In_ PB57XX_ADAPTER Adapter) { - USHORT AddressWord; + B57XXWriteMailbox(Adapter, B57XX_MBOX_INT_MAILBOX0, (Adapter->Status.LastTag & 0xFF) << 24); +} - NDIS_MinDbgPrint("NICGetPermanentMacAddress\n"); +VOID +NTAPI +NICReceiveSignalComplete(_In_ PB57XX_ADAPTER Adapter) +{ + B57XXWriteMailbox(Adapter, B57XX_MBOX_RXC_RET_RING_INDEX1, Adapter->ReturnConsumer[0].Index); + B57XXWriteMailbox(Adapter, B57XX_MBOX_STD_RXP_RING_INDEX, Adapter->StandardProducer.Index); +} - /* Should we read from RAL/RAH first? */ - for (UINT n = 0; n < (IEEE_802_ADDR_LENGTH / 2); n++) +VOID +NTAPI +NICQueryStatisticCounter(_In_ PB57XX_ADAPTER Adapter, + _In_ NDIS_OID Oid, + _Out_ PULONG64 pValue64) +{ + *pValue64 = 0; + + if (Adapter->HardwareStatus != NdisHardwareStatusReady) { - if (!B57XXReadEeprom(Adapter, (UCHAR)n, &AddressWord)) - { - return NDIS_STATUS_FAILURE; - } - Adapter->PermanentMacAddress[n * 2 + 0] = AddressWord & 0xff; - Adapter->PermanentMacAddress[n * 2 + 1] = (AddressWord >> 8) & 0xff; + return; } + + switch (Oid) + { + case OID_GEN_XMIT_OK: + *pValue64 = Adapter->Statistics.TransmitSuccesses; + break; + case OID_GEN_RCV_OK: + *pValue64 = Adapter->Statistics.ReceiveSuccesses; + break; + case OID_GEN_XMIT_ERROR: + *pValue64 = Adapter->Statistics.TransmitErrors; + break; + case OID_GEN_RCV_ERROR: + *pValue64 = Adapter->Statistics.ReceiveErrors; + break; + case OID_GEN_RCV_NO_BUFFER: + *pValue64 = Adapter->Statistics.ReceiveBufferErrors; + break; + case OID_GEN_DIRECTED_FRAMES_XMIT: // ifHCOutUcastPkts + B57XXReadStatistic(Adapter, 0x3D8, 0x086C, FALSE, pValue64); + break; + case OID_GEN_MULTICAST_FRAMES_XMIT: // ifHCOutMulticastPkts + B57XXReadStatistic(Adapter, 0x3E0, 0x0870, FALSE, pValue64); + break; + case OID_GEN_BROADCAST_FRAMES_XMIT: // ifHCOutBroadcastPkts + B57XXReadStatistic(Adapter, 0x3E8, 0x0874, FALSE, pValue64); + break; + case OID_GEN_DIRECTED_FRAMES_RCV: // ifHCInUcastPkts + B57XXReadStatistic(Adapter, 0x118, 0x088C, FALSE, pValue64); + break; + case OID_GEN_MULTICAST_FRAMES_RCV: // ifHCInMulticastPkts + B57XXReadStatistic(Adapter, 0x120, 0x0890, FALSE, pValue64); + break; + case OID_GEN_BROADCAST_FRAMES_RCV: // ifHCInBroadcastPkts + B57XXReadStatistic(Adapter, 0x120, 0x0894, FALSE, pValue64); + break; + default: + NDIS_MinDbgPrint("Unknown statistic (0x%x)", Oid); + } +} - NDIS_MinDbgPrint("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", - Adapter->PermanentMacAddress[0], - Adapter->PermanentMacAddress[1], - Adapter->PermanentMacAddress[2], - Adapter->PermanentMacAddress[3], - Adapter->PermanentMacAddress[4], - Adapter->PermanentMacAddress[5]); +NDIS_STATUS +NTAPI +NICFillPowerManagementCapabilities(_In_ PB57XX_ADAPTER Adapter, + _Out_ PNDIS_PNP_CAPABILITIES Capabilities) +{ + /* TODO Fill with real power management capabilities. + See the chapter "Power management" in corresponding manuals */ + Capabilities->WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateUnspecified; + Capabilities->WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateUnspecified; + return NDIS_STATUS_SUCCESS; } -NDIS_STATUS +VOID NTAPI -NICUpdateMulticastList(IN PB57XX_ADAPTER Adapter) +NICOutputDebugInfo(_In_ PB57XX_ADAPTER Adapter) { - NDIS_MinDbgPrint("NICUpdateMulticastList\n"); + ULONG Value; + ULONG ExtraValue; + + B57XXReadULong(Adapter, B57XX_REG_FLOW_ATTENTION, &Value); + NDIS_MinDbgPrint("Flow attention: 0x%x\n", Value); + + B57XXReadULong(Adapter, B57XX_REG_ETH_MAC_STATUS, &Value); + NDIS_MinDbgPrint("Ethernet MAC Status: 0x%x\n", Value); + + B57XXReadULong(Adapter, B57XX_REG_MSI_MODE, &Value); + B57XXReadULong(Adapter, B57XX_REG_MSI_STATUS, &ExtraValue); + NDIS_MinDbgPrint("MSI: (Mode: 0x%x, Status: 0x%x)\n", Value, ExtraValue); + + B57XXReadULong(Adapter, B57XX_REG_DMA_READ_STATUS, &Value); + B57XXReadULong(Adapter, B57XX_REG_DMA_WRITE_STATUS, &ExtraValue); + NDIS_MinDbgPrint("DMA: (Read: 0x%x, Write: 0x%x)\n", Value, ExtraValue); + + B57XXReadRegister(Adapter, B57XX_REG_RX_RISC_STATE, &Value); + B57XXReadRegister(Adapter, B57XX_REG_RX_RISC_MODE, &ExtraValue); + NDIS_MinDbgPrint("RX RISC: (State: 0x%x, Mode: 0x%x)\n", Value, ExtraValue); + + B57XXReadRegister(Adapter, B57XX_REG_TX_RISC_STATE, &Value); + B57XXReadRegister(Adapter, B57XX_REG_TX_RISC_MODE, &ExtraValue); + NDIS_MinDbgPrint("TX RISC: (State: 0x%x, Mode: 0x%x)\n", Value, ExtraValue); +} - for (UINT n = 0; n < MAXIMUM_MULTICAST_ADDRESSES; ++n) - { - /*ULONG Ral = *(ULONG*)Adapter->MulticastList[n].MacAddress; - ULONG Rah = *(USHORT*)&Adapter->MulticastList[n].MacAddress[4]; +/* B57XX FUNCTIONS ********************************************************************************/ - if (Rah || Ral) - { - Rah |= B57XX_RAH_AV; +VOID +B57XXWriteMemoryRCB(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Address, + _In_ volatile PB57XX_RING_CONTROL_BLOCK pRCB) +{ + ULONG AddressBase = Address & 0xFFFF0000; + ULONG Offset = B57XX_REG_MEM_WINDOW + (Address & 0x0000FFFF); + + B57XXWritePciConfigULong(Adapter, B57XX_REG_MEM_BASE, AddressBase); + *(PB57XX_RING_CONTROL_BLOCK)(Adapter->IoBase + Offset) = *pRCB; + + B57XXWritePciConfigULong(Adapter, B57XX_REG_MEM_BASE, 0); +} - B57XXWriteUlong(Adapter, B57XX_REG_RAL + (8*n), Ral); - B57XXWriteUlong(Adapter, B57XX_REG_RAH + (8*n), Rah); - } - else +NDIS_STATUS +B57XXReadPHY(_In_ PB57XX_ADAPTER Adapter, + _In_ USHORT PHYRegOffset, + _Out_ PUSHORT pValue) +{ + ULONG Value32; + USHORT PHYAddress = 0x01; + + B57XXWriteULong(Adapter, + B57XX_REG_ETH_MI_COMMUNICATION, + ((ULONG)PHYAddress << 21) | + ((ULONG)PHYRegOffset << 16) | + B57XX_ETH_MI_COMMUNICATION_START | + (0b10 << 26)); + + for (UINT n = 0; n < MAX_ATTEMPTS_PHY; n++) + { + B57XXReadULong(Adapter, B57XX_REG_ETH_MI_COMMUNICATION, &Value32); + if (!(Value32 & B57XX_ETH_MI_COMMUNICATION_START)) { - B57XXWriteUlong(Adapter, B57XX_REG_RAH + (8*n), 0); - B57XXWriteUlong(Adapter, B57XX_REG_RAL + (8*n), 0); - }*/ + break; + } + NdisStallExecution(1); } - + if (Value32 & B57XX_ETH_MI_COMMUNICATION_START) + { + NDIS_MinDbgPrint("Unable to read to PHY, timed out (0x%x)\n", Value32); + return NDIS_STATUS_FAILURE; + } + + *pValue = Value32 & 0xFFFF; + return NDIS_STATUS_SUCCESS; } NDIS_STATUS -NTAPI -NICApplyPacketFilter(IN PB57XX_ADAPTER Adapter) +B57XXWritePHY(_In_ PB57XX_ADAPTER Adapter, + _In_ USHORT PHYRegOffset, + _In_ USHORT Value) { - //ULONG FilterMask; - NDIS_MinDbgPrint("NICApplyPacketFilter\n"); - - /*B57XXReadUlong(Adapter, B57XX_REG_RCTL, &FilterMask); - - FilterMask &= ~B57XX_RCTL_FILTER_BITS; - FilterMask |= PacketFilterToMask(Adapter->PacketFilter); - B57XXWriteUlong(Adapter, B57XX_REG_RCTL, FilterMask); + ULONG Value32; + USHORT PHYAddress = 0x01; + + B57XXWriteULong(Adapter, + B57XX_REG_ETH_MI_COMMUNICATION, + ((ULONG)PHYAddress << 21) | + ((ULONG)PHYRegOffset << 16) | + (ULONG)Value | + B57XX_ETH_MI_COMMUNICATION_START | + (0b01 << 26)); + + for (UINT n = 0; n < MAX_ATTEMPTS_PHY; n++) + { + B57XXReadULong(Adapter, B57XX_REG_ETH_MI_COMMUNICATION, &Value32); + if (!(Value32 & B57XX_ETH_MI_COMMUNICATION_START)) + { + break; + } + NdisStallExecution(1); + } + if (Value32 & B57XX_ETH_MI_COMMUNICATION_START) + { + NDIS_MinDbgPrint("Unable to write to PHY, timed out (0x%x)\n", Value32); + return NDIS_STATUS_FAILURE; + } + + return NDIS_STATUS_SUCCESS; +} - return NDIS_STATUS_SUCCESS;*/ +VOID +B57XXClearMACAttentions(_In_ PB57XX_ADAPTER Adapter) +{ + ULONG Value; - return NDIS_STATUS_FAILURE; + B57XXEnableRegister(Adapter, + B57XX_REG_ETH_MAC_STATUS, + &Value, + B57XX_ETH_MAC_STATUS_CONFIGCHANGED | + B57XX_ETH_MAC_STATUS_SYNCCHANGED | + B57XX_ETH_MAC_STATUS_MICOMPLETE); } VOID -NTAPI -NICUpdateLinkStatus(IN PB57XX_ADAPTER Adapter) +B57XXReadAndClearPHYInterrupts(_In_ PB57XX_ADAPTER Adapter, + _Out_ PUSHORT Interrupts) { - /*ULONG DeviceStatus; - SIZE_T SpeedIndex; - static ULONG SpeedValues[] = {10, 100, 1000, 1000};*/ - - NDIS_MinDbgPrint("NICUpdateLinkStatus\n"); - - /*B57XXReadUlong(Adapter, B57XX_REG_STATUS, &DeviceStatus); - Adapter->MediaState = (DeviceStatus & B57XX_STATUS_LU) ? - NdisMediaStateConnected : - NdisMediaStateDisconnected; - SpeedIndex = (DeviceStatus & B57XX_STATUS_SPEEDMASK) >> B57XX_STATUS_SPEEDSHIFT; - Adapter->LinkSpeedMbps = SpeedValues[SpeedIndex];*/ + USHORT Dummy; + + B57XXReadPHY(Adapter, B57XX_MII_REG_INT_STATUS, Interrupts); + // Read again to clear + B57XXReadPHY(Adapter, B57XX_MII_REG_INT_STATUS, &Dummy); } -/* B57XX FUNCTIONS ************************************************************/ +VOID +B57XXReadStatistic(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG BlockOffset, + _In_ ULONG RegOffset, + _In_ BOOLEAN Is64Bit, + _Out_ PULONG64 pValue64) +{ + PULARGE_INTEGER pLargeInt = (PULARGE_INTEGER)pValue64; + + if (!Adapter->B5705Plus) + { + if (Is64Bit) + { + pLargeInt->HighPart = *(PULONG)((PUCHAR)Adapter->Statistics.pBlock + BlockOffset + 0); + pLargeInt->LowPart = *(PULONG)((PUCHAR)Adapter->Statistics.pBlock + BlockOffset + 4); + } + else + { + pLargeInt->LowPart = *(PULONG)((PUCHAR)Adapter->Statistics.pBlock + BlockOffset); + } + } + else + { + if (Is64Bit) + { + B57XXReadULong(Adapter, RegOffset + 0, &pLargeInt->HighPart); + B57XXReadULong(Adapter, RegOffset + 4, &pLargeInt->LowPart); + } + else + { + B57XXReadULong(Adapter, RegOffset, &pLargeInt->LowPart); + } + } +} -BOOLEAN -B57XXReadEeprom(IN PB57XX_ADAPTER Adapter, - IN UCHAR Address, - USHORT *Result) +VOID +B57XXAccumulateAddress(_Out_ PB57XX_PHYSICAL_ADDRESS pDestination, + _In_ LONG Offset) { - //ULONG Value; + NDIS_PHYSICAL_ADDRESS Address; + + Address.HighPart = pDestination->HighPart; + Address.LowPart = pDestination->LowPart; + + Address.QuadPart += Offset; + + pDestination->HighPart = Address.HighPart; + pDestination->LowPart = Address.LowPart; +} - for (UINT n = 0; n < MAX_EEPROM_READ_ATTEMPTS; n++) +ULONG +B57XXComputeInverseCrc32(_In_ PUCHAR pBuffer, + _In_ ULONG BufferSize) +{ + ULONG Tmp; + ULONG Reg = 0xFFFFFFFF; + + for(ULONG i = 0; i < BufferSize; i++) { - NdisStallExecution(5); + Reg ^= pBuffer[i]; - // TODO - // B57XXReadEeprom(Adapter, ???, &Value); - - /*if (Value & B57XX_EERD_DONE) + for(ULONG j = 0; j < 8; j++) { - break; - }*/ + Tmp = Reg & 0x01; + Reg >>= 1; + if(Tmp) + { + Reg ^= 0xEDB88320; + } + } } - /*if (!(Value & B57XX_EERD_DONE)) - { - NDIS_MinDbgPrint("EEPROM Read incomplete\n"); - return FALSE; - }*/ - //*Result = (USHORT)(Value >> B57XX_EERD_DATA_SHIFT); - return TRUE; + return Reg; } diff --git a/drivers/network/dd/b57xx/info.c b/drivers/network/dd/b57xx/info.c index 869beb4a2eea7..72849df0234a0 100644 --- a/drivers/network/dd/b57xx/info.c +++ b/drivers/network/dd/b57xx/info.c @@ -2,15 +2,17 @@ * PROJECT: ReactOS Broadcom NetXtreme Driver * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: Miniport information callbacks - * COPYRIGHT: Copyright 2021 Scott Maday + * COPYRIGHT: Copyright 2021-2022 Scott Maday */ #include "nic.h" -#include "debug.h" +#define NDEBUG +#include static NDIS_OID SupportedOidList[] = { + /* Required OIDs */ OID_GEN_SUPPORTED_LIST, OID_GEN_CURRENT_PACKET_FILTER, OID_GEN_HARDWARE_STATUS, @@ -36,23 +38,37 @@ static NDIS_OID SupportedOidList[] = OID_802_3_PERMANENT_ADDRESS, OID_802_3_CURRENT_ADDRESS, OID_802_3_MAXIMUM_LIST_SIZE, + + /* Optional OIDs */ + OID_GEN_PHYSICAL_MEDIUM, + + /* PnP and Power Management */ + OID_PNP_CAPABILITIES, - /* Statistics */ + /* Required statistics */ OID_GEN_XMIT_OK, OID_GEN_RCV_OK, OID_GEN_XMIT_ERROR, OID_GEN_RCV_ERROR, OID_GEN_RCV_NO_BUFFER, + + /* Optional statistics */ + OID_GEN_DIRECTED_FRAMES_XMIT, + OID_GEN_MULTICAST_FRAMES_XMIT, + OID_GEN_BROADCAST_FRAMES_XMIT, + OID_GEN_DIRECTED_FRAMES_RCV, + OID_GEN_MULTICAST_FRAMES_RCV, + OID_GEN_BROADCAST_FRAMES_RCV }; NDIS_STATUS NTAPI -MiniportQueryInformation(IN NDIS_HANDLE MiniportAdapterContext, - IN NDIS_OID Oid, - IN PVOID InformationBuffer, - IN ULONG InformationBufferLength, - OUT PULONG BytesWritten, - OUT PULONG BytesNeeded) +MiniportQueryInformation(_In_ NDIS_HANDLE MiniportAdapterContext, + _In_ NDIS_OID Oid, + _In_ PVOID InformationBuffer, + _In_ ULONG InformationBufferLength, + _Out_ PULONG BytesWritten, + _Out_ PULONG BytesNeeded) { NDIS_STATUS Status = NDIS_STATUS_SUCCESS; PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; @@ -62,15 +78,17 @@ MiniportQueryInformation(IN NDIS_HANDLE MiniportAdapterContext, ULONG ULong; ULONG64 ULong64; NDIS_MEDIUM Medium; - NDIS_PNP_CAPABILITIES PmCapabilities; + NDIS_PNP_CAPABILITIES PMCapabilities; } GenericInfo; PVOID CopySource = &GenericInfo; ULONG CopyLength = sizeof(ULONG); + + NdisAcquireSpinLock(&Adapter->InfoLock); switch (Oid) { case OID_GEN_SUPPORTED_LIST: - CopySource = (PVOID)&SupportedOidList; + CopySource = (PVOID)SupportedOidList; CopyLength = sizeof(SupportedOidList); break; @@ -79,10 +97,10 @@ MiniportQueryInformation(IN NDIS_HANDLE MiniportAdapterContext, break; case OID_GEN_HARDWARE_STATUS: - UNIMPLEMENTED_DBGBREAK(); - GenericInfo.ULong = (ULONG)NdisHardwareStatusReady; // FIXME + NDIS_MinDbgPrint("Hardware status: %d\n", Adapter->HardwareStatus); + GenericInfo.ULong = (ULONG)Adapter->HardwareStatus; break; - + case OID_GEN_MEDIA_SUPPORTED: case OID_GEN_MEDIA_IN_USE: { @@ -96,7 +114,7 @@ MiniportQueryInformation(IN NDIS_HANDLE MiniportAdapterContext, case OID_GEN_CURRENT_LOOKAHEAD: case OID_GEN_MAXIMUM_LOOKAHEAD: case OID_GEN_MAXIMUM_FRAME_SIZE: - GenericInfo.ULong = MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER); + GenericInfo.ULong = Adapter->MaxFrameSize - sizeof(ETH_HEADER); break; case OID_802_3_MULTICAST_LIST: @@ -109,22 +127,40 @@ MiniportQueryInformation(IN NDIS_HANDLE MiniportAdapterContext, break; case OID_GEN_LINK_SPEED: - GenericInfo.ULong = Adapter->LinkSpeedMbps * 10000; + switch (Adapter->LinkStatus & (0b111 << 8)) + { + case B57XX_PHY_AUX_STATUS_MODE_10TH: + case B57XX_PHY_AUX_STATUS_MODE_10TF: + GenericInfo.ULong = 10; + break; + case B57XX_PHY_AUX_STATUS_MODE_100TXH: + case B57XX_PHY_AUX_STATUS_MODE_100T4: + case B57XX_PHY_AUX_STATUS_MODE_100TXF: + GenericInfo.ULong = 100; + break; + case B57XX_PHY_AUX_STATUS_MODE_1000TH: + case B57XX_PHY_AUX_STATUS_MODE_1000TF: + GenericInfo.ULong = 1000; + break; + default: + GenericInfo.ULong = 0; + } + GenericInfo.ULong *= 10000; break; case OID_GEN_TRANSMIT_BUFFER_SPACE: - GenericInfo.ULong = MAXIMUM_FRAME_SIZE; + GenericInfo.ULong = Adapter->MaxFrameSize; break; case OID_GEN_RECEIVE_BUFFER_SPACE: - GenericInfo.ULong = RECEIVE_BUFFER_SIZE; + GenericInfo.ULong = Adapter->MaxFrameSize; break; case OID_GEN_VENDOR_ID: /* The 3 bytes of the MAC address is the vendor ID */ - GenericInfo.ULong = ((ULONG)Adapter->PermanentMacAddress[0] << 16) | - ((ULONG)Adapter->PermanentMacAddress[1] << 8) | - ((ULONG)Adapter->PermanentMacAddress[2] & 0xFF); + GenericInfo.ULong = ((ULONG)Adapter->MACAddresses[0][0] << 16) | + ((ULONG)Adapter->MACAddresses[0][1] << 8) | + ((ULONG)Adapter->MACAddresses[0][2] & 0xFF); break; case OID_GEN_VENDOR_DESCRIPTION: @@ -142,12 +178,12 @@ MiniportQueryInformation(IN NDIS_HANDLE MiniportAdapterContext, case OID_GEN_DRIVER_VERSION: { CopyLength = sizeof(USHORT); - GenericInfo.UShort = (NDIS_MINIPORT_MAJOR_VERSION << 8) + NDIS_MINIPORT_MINOR_VERSION; + GenericInfo.UShort = (NDIS_MINIPORT_MAJOR_VERSION << 8) | NDIS_MINIPORT_MINOR_VERSION; break; } case OID_GEN_MAXIMUM_TOTAL_SIZE: - GenericInfo.ULong = MAXIMUM_FRAME_SIZE; + GenericInfo.ULong = Adapter->MaxFrameSize; break; case OID_GEN_MAXIMUM_SEND_PACKETS: @@ -158,30 +194,44 @@ MiniportQueryInformation(IN NDIS_HANDLE MiniportAdapterContext, GenericInfo.ULong = NDIS_MAC_OPTION_RECEIVE_SERIALIZED | NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | - NDIS_MAC_OPTION_NO_LOOPBACK; + NDIS_MAC_OPTION_NO_LOOPBACK | + NDIS_MAC_OPTION_FULL_DUPLEX; break; case OID_GEN_MEDIA_CONNECT_STATUS: - GenericInfo.ULong = Adapter->MediaState; + GenericInfo.ULong = Adapter->LinkStatus & B57XX_PHY_AUX_STATUS_LINKSTATUS ? + NdisMediaStateConnected : NdisMediaStateDisconnected; break; - + + case OID_802_3_PERMANENT_ADDRESS: case OID_802_3_CURRENT_ADDRESS: - CopySource = Adapter->MulticastList[0].MacAddress; + CopySource = Adapter->MACAddresses[0]; CopyLength = IEEE_802_ADDR_LENGTH; break; - - case OID_802_3_PERMANENT_ADDRESS: - CopySource = Adapter->PermanentMacAddress; - CopyLength = IEEE_802_ADDR_LENGTH; + + case OID_GEN_PHYSICAL_MEDIUM: + GenericInfo.ULong = NdisPhysicalMedium802_3; break; + + case OID_PNP_CAPABILITIES: + CopyLength = sizeof(NDIS_PNP_CAPABILITIES); + Status = NICFillPowerManagementCapabilities(Adapter, &GenericInfo.PMCapabilities); + break; + case OID_GEN_XMIT_OK: case OID_GEN_RCV_OK: case OID_GEN_XMIT_ERROR: case OID_GEN_RCV_ERROR: case OID_GEN_RCV_NO_BUFFER: + case OID_GEN_DIRECTED_FRAMES_XMIT: + case OID_GEN_MULTICAST_FRAMES_XMIT: + case OID_GEN_BROADCAST_FRAMES_XMIT: + case OID_GEN_DIRECTED_FRAMES_RCV: + case OID_GEN_MULTICAST_FRAMES_RCV: + case OID_GEN_BROADCAST_FRAMES_RCV: { - //GenericInfo.ULong64 = NICQueryStatisticCounter(Adapter, Oid); TODO + NICQueryStatisticCounter(Adapter, Oid, &GenericInfo.ULong64); *BytesNeeded = sizeof(ULONG64); if (InformationBufferLength >= sizeof(ULONG64)) @@ -197,9 +247,11 @@ MiniportQueryInformation(IN NDIS_HANDLE MiniportAdapterContext, else { *BytesWritten = 0; - return NDIS_STATUS_BUFFER_TOO_SHORT; + Status = NDIS_STATUS_BUFFER_TOO_SHORT; + goto Exit; } - return NDIS_STATUS_SUCCESS; + Status = NDIS_STATUS_SUCCESS; + goto Exit; } default: @@ -235,22 +287,28 @@ MiniportQueryInformation(IN NDIS_HANDLE MiniportAdapterContext, Status, *BytesWritten, *BytesNeeded); + + +Exit: + NdisReleaseSpinLock(&Adapter->InfoLock); return Status; } NDIS_STATUS NTAPI -MiniportSetInformation(IN NDIS_HANDLE MiniportAdapterContext, - IN NDIS_OID Oid, - IN PVOID InformationBuffer, - IN ULONG InformationBufferLength, - OUT PULONG BytesRead, - OUT PULONG BytesNeeded) +MiniportSetInformation(_In_ NDIS_HANDLE MiniportAdapterContext, + _In_ NDIS_OID Oid, + _In_ PVOID InformationBuffer, + _In_ ULONG InformationBufferLength, + _Out_ PULONG BytesRead, + _Out_ PULONG BytesNeeded) { NDIS_STATUS Status = NDIS_STATUS_SUCCESS; PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; ULONG GenericULong; + + NdisAcquireSpinLock(&Adapter->InfoLock); switch (Oid) { @@ -270,8 +328,7 @@ MiniportSetInformation(IN NDIS_HANDLE MiniportAdapterContext, NDIS_PACKET_TYPE_MULTICAST | NDIS_PACKET_TYPE_ALL_MULTICAST | NDIS_PACKET_TYPE_BROADCAST | - NDIS_PACKET_TYPE_PROMISCUOUS | - NDIS_PACKET_TYPE_MAC_FRAME)) + NDIS_PACKET_TYPE_PROMISCUOUS)) { *BytesRead = sizeof(ULONG); *BytesNeeded = sizeof(ULONG); @@ -306,7 +363,7 @@ MiniportSetInformation(IN NDIS_HANDLE MiniportAdapterContext, NdisMoveMemory(&GenericULong, InformationBuffer, sizeof(ULONG)); - if (GenericULong > MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER)) + if (GenericULong > Adapter->MaxFrameSize - sizeof(ETH_HEADER)) { Status = NDIS_STATUS_INVALID_DATA; } @@ -352,6 +409,8 @@ MiniportSetInformation(IN NDIS_HANDLE MiniportAdapterContext, *BytesNeeded = 0; } + NdisReleaseSpinLock(&Adapter->InfoLock); + NDIS_MinDbgPrint("Set Info on OID 0x%x: %s(0x%x) (%d, %d)\n", Oid, Status == NDIS_STATUS_SUCCESS ? "Completed" : "Failed", diff --git a/drivers/network/dd/b57xx/interrupt.c b/drivers/network/dd/b57xx/interrupt.c index 130106ef50b72..2dd7dcccf51b5 100644 --- a/drivers/network/dd/b57xx/interrupt.c +++ b/drivers/network/dd/b57xx/interrupt.c @@ -2,50 +2,176 @@ * PROJECT: ReactOS Broadcom NetXtreme Driver * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: Interrupt handlers - * COPYRIGHT: Copyright 2021 Scott Maday + * COPYRIGHT: Copyright 2021-2022 Scott Maday */ #include "nic.h" -#include "debug.h" +#define NDEBUG +#include VOID NTAPI -MiniportISR(OUT PBOOLEAN InterruptRecognized, - OUT PBOOLEAN QueueMiniportHandleInterrupt, - IN NDIS_HANDLE MiniportAdapterContext) +MiniportDisableInterrupt(_In_ NDIS_HANDLE MiniportAdapterContext) { - //ULONG Value; - //PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; + PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; - NDIS_MinDbgPrint("B57XX ISR\n"); - - /* Reading the interrupt acknowledges them */ - /*B57XXReadUlong(Adapter, B57XX_REG_ICR, &Value); + NICDisableInterrupts(Adapter); +} - Value &= Adapter->InterruptMask; - _InterlockedOr(&Adapter->InterruptPending, Value); +VOID +NTAPI +MiniportEnableInterrupt(_In_ NDIS_HANDLE MiniportAdapterContext) +{ + PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; + + NICEnableInterrupts(Adapter); +} - if (Value) +VOID +NTAPI +MiniportISR(_Out_ PBOOLEAN InterruptRecognized, + _Out_ PBOOLEAN QueueMiniportHandleInterrupt, + _In_ NDIS_HANDLE MiniportAdapterContext) +{ + PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; + + if (Adapter->Status.pBlock->Status & B57XX_SB_UPDATED && Adapter->Interrupt.Pending == FALSE) { + NICInterruptAcknowledge(Adapter); + + Adapter->Status.LastTag = Adapter->Status.pBlock->StatusTag; + Adapter->Status.pBlock->Status &= ~B57XX_SB_UPDATED; + + Adapter->Interrupt.Pending = TRUE; + *InterruptRecognized = TRUE; - // Mark the events pending service *QueueMiniportHandleInterrupt = TRUE; } else { - // This is not ours. *InterruptRecognized = FALSE; *QueueMiniportHandleInterrupt = FALSE; - }*/ + } } VOID NTAPI -MiniportHandleInterrupt(IN NDIS_HANDLE MiniportAdapterContext) +MiniportHandleInterrupt(_In_ NDIS_HANDLE MiniportAdapterContext) { - //ULONG InterruptPending; - //PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; + ULONG ProducerIndex; + ULONG ConsumerIndex; + PCHAR BufferBase; + PB57XX_RECEIVE_BUFFER_DESCRIPTOR pReceiveDescriptor; + PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; + BOOLEAN LinkStateChange = FALSE; + BOOLEAN GotAny = FALSE; + + if (Adapter->HardwareStatus != NdisHardwareStatusReady) + { + return; + } + + NdisDprAcquireSpinLock(&Adapter->Interrupt.Lock); + if (Adapter->Interrupt.Pending == FALSE) + { + return; + } + Adapter->Interrupt.Pending = FALSE; + + do + { + Adapter->Status.pBlock->Status &= ~B57XX_SB_UPDATED; + + /* Process any link changes */ + if (Adapter->Status.pBlock->Status & B57XX_SB_LINKSTATE) + { + Adapter->Status.pBlock->Status &= ~B57XX_SB_LINKSTATE; + + LinkStateChange = TRUE; + NDIS_MinDbgPrint("Link state change\n"); + + NdisMIndicateStatus(Adapter->MiniportAdapterHandle, + NICUpdateLinkStatus(Adapter), + NULL, + 0); + NdisMIndicateStatusComplete(Adapter->MiniportAdapterHandle); + } + + /* Process any received frames (receive interrupts) */ + while (Adapter->ReturnConsumer[0].Index != + Adapter->Status.pBlock->RingIndexPairs[0].ReceiveProducerIndex) + { + ConsumerIndex = Adapter->ReturnConsumer[0].Index; + ProducerIndex = Adapter->StandardProducer.Index; + pReceiveDescriptor = Adapter->ReturnConsumer[0].pRing + ConsumerIndex; + + if (pReceiveDescriptor->Flags & B57XX_RBD_FRAME_HAS_ERROR) + { + NDIS_MinDbgPrint("RX error (0x%x)\n", pReceiveDescriptor->Flags); + Adapter->Statistics.ReceiveErrors++; + goto ContinueReceive; + } + + BufferBase = (PCHAR)Adapter->StandardProducer.HostBuffer + + Adapter->StandardProducer.FrameBufferLength * pReceiveDescriptor->Index; + + NdisMEthIndicateReceive(Adapter->MiniportAdapterHandle, + NULL, + BufferBase, + sizeof(ETH_HEADER), + BufferBase + sizeof(ETH_HEADER), + pReceiveDescriptor->Length - sizeof(ETH_HEADER), + pReceiveDescriptor->Length - sizeof(ETH_HEADER)); + GotAny = TRUE; + + Adapter->Statistics.ReceiveSuccesses++; - NDIS_MinDbgPrint("B57XX HandleInterrupt\n"); +ContinueReceive: + ConsumerIndex = (ConsumerIndex + 1) % Adapter->ReturnConsumer[0].Count; + Adapter->ReturnConsumer[0].Index = ConsumerIndex; + + ProducerIndex = (ProducerIndex + 1) % Adapter->StandardProducer.Count; + Adapter->StandardProducer.Index = ProducerIndex; + } + + if (GotAny) + { + NICReceiveSignalComplete(Adapter); + NdisMEthIndicateReceiveComplete(Adapter->MiniportAdapterHandle); + } + + /* Process any completed frames (transmit interrupts) */ + while (Adapter->SendProducer[0].ConsumerIndex != + Adapter->Status.pBlock->RingIndexPairs[0].SendConsumerIndex) + { + ConsumerIndex = Adapter->SendProducer[0].ConsumerIndex; + + NdisMSendComplete(Adapter->MiniportAdapterHandle, + Adapter->SendProducer[0].pPacketList[ConsumerIndex], + NDIS_STATUS_SUCCESS); + Adapter->SendProducer[0].RingFull = FALSE; + + Adapter->Statistics.TransmitSuccesses++; + + ConsumerIndex = (ConsumerIndex + 1) % Adapter->SendProducer[0].Count; + Adapter->SendProducer[0].ConsumerIndex = ConsumerIndex; + } + } + while (NICInterruptCheckAvailability(Adapter)); + + if (Adapter->Status.pBlock->Status & B57XX_SB_ERROR) + { + // It may "error" due to the link state change generating a MAC attention + if (LinkStateChange == FALSE) + { + NDIS_MinDbgPrint("Error detected\n"); + NICOutputDebugInfo(Adapter); + } + + Adapter->Status.pBlock->Status &= ~B57XX_SB_ERROR; + } + + NICInterruptSignalComplete(Adapter); + NdisDprReleaseSpinLock(&Adapter->Interrupt.Lock); } diff --git a/drivers/network/dd/b57xx/ndis.c b/drivers/network/dd/b57xx/ndis.c index d46e31f3646f9..d510024fb42be 100644 --- a/drivers/network/dd/b57xx/ndis.c +++ b/drivers/network/dd/b57xx/ndis.c @@ -1,59 +1,115 @@ /* * PROJECT: ReactOS Broadcom NetXtreme Driver * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) - * PURPOSE: Driver entrypoint - * COPYRIGHT: Copyright 2021 Scott Maday + * PURPOSE: Driver entrypoint and miscellaneous miniport functions + * COPYRIGHT: Copyright 2021-2022 Scott Maday */ + #include "nic.h" -#include "debug.h" +#define NDEBUG +#include ULONG DebugTraceLevel = MIN_TRACE; +static NDIS_STATUS -NTAPI -MiniportReset(OUT PBOOLEAN AddressingReset, - IN NDIS_HANDLE MiniportAdapterContext) +InitAdapterResources(_In_ PB57XX_ADAPTER Adapter, + _In_ PNDIS_RESOURCE_LIST ResourceList) { - //PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; - - *AddressingReset = FALSE; - UNIMPLEMENTED_DBGBREAK(); - return NDIS_STATUS_FAILURE; -} + for (UINT n = 0; n < ResourceList->Count; n++) + { + PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor = ResourceList->PartialDescriptors + n; -VOID -NTAPI -MiniportHalt(IN NDIS_HANDLE MiniportAdapterContext) -{ - PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; - - ASSERT(Adapter != NULL); + switch (ResourceDescriptor->Type) + { + case CmResourceTypeInterrupt: + ASSERT(Adapter->Interrupt.Vector == 0); + ASSERT(Adapter->Interrupt.Level == 0); + + Adapter->Interrupt.Vector = ResourceDescriptor->u.Interrupt.Vector; + Adapter->Interrupt.Level = ResourceDescriptor->u.Interrupt.Level; + Adapter->Interrupt.Shared = (ResourceDescriptor->ShareDisposition == + CmResourceShareShared); + Adapter->Interrupt.Flags = ResourceDescriptor->Flags; + break; + case CmResourceTypeMemory: + ASSERT(Adapter->IoAddress.LowPart == 0); + + Adapter->IoAddress.QuadPart = ResourceDescriptor->u.Memory.Start.QuadPart; + Adapter->IoLength = ResourceDescriptor->u.Memory.Length; + break; + + default: + break; + } + } - /* First disable sending / receiving */ - NICDisableTxRx(Adapter); + if (Adapter->IoAddress.QuadPart == 0 || Adapter->Interrupt.Vector == 0) + { + NDIS_MinDbgPrint("Adapter didn't receive enough resources\n"); + return NDIS_STATUS_RESOURCES; + } - /* Then unregister interrupts */ - NICUnregisterInterrupts(Adapter); + return NDIS_STATUS_SUCCESS; +} - /* Finally, free other resources (Ports, IO ranges,...) */ - NICReleaseIoResources(Adapter); +static +NDIS_STATUS +InitAllocateSharedMemory(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Length, + _Out_ PVOID* pVirtualAddress, + _Out_ PB57XX_PHYSICAL_ADDRESS pPhysicalAddress) +{ + NDIS_PHYSICAL_ADDRESS Tmp; + + NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, Length, FALSE, pVirtualAddress, &Tmp); + if (*pVirtualAddress == NULL) + { + return NDIS_STATUS_RESOURCES; + } + + NdisZeroMemory(*pVirtualAddress, Length); + + B57XXConvertAddress(pPhysicalAddress, &Tmp); + + return NDIS_STATUS_SUCCESS; +} - /* Destroy the adapter context */ - NdisFreeMemory(Adapter, sizeof(*Adapter), 0); +static +NDIS_STATUS +FreeSharedMemory(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Length, + _In_ PVOID VirtualAddress, + _In_ PB57XX_PHYSICAL_ADDRESS pPhysicalAddress) +{ + NDIS_PHYSICAL_ADDRESS Tmp; + + if (VirtualAddress == NULL) + { + return NDIS_STATUS_SOFT_ERRORS; + } + + Tmp.HighPart = pPhysicalAddress->HighPart; + Tmp.LowPart = pPhysicalAddress->LowPart; + + NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Length, FALSE, VirtualAddress, Tmp); + + return NDIS_STATUS_SUCCESS; } NDIS_STATUS NTAPI -MiniportInitialize(OUT PNDIS_STATUS OpenErrorStatus, - OUT PUINT SelectedMediumIndex, - IN PNDIS_MEDIUM MediumArray, - IN UINT MediumArraySize, - IN NDIS_HANDLE MiniportAdapterHandle, - IN NDIS_HANDLE WrapperConfigurationContext) +MiniportInitialize(_Out_ PNDIS_STATUS OpenErrorStatus, + _Out_ PUINT SelectedMediumIndex, + _In_ PNDIS_MEDIUM MediumArray, + _In_ UINT MediumArraySize, + _In_ NDIS_HANDLE MiniportAdapterHandle, + _In_ NDIS_HANDLE WrapperConfigurationContext) { NDIS_STATUS Status; PB57XX_ADAPTER Adapter; + PCI_COMMON_CONFIG PCIConfig; UINT i; PNDIS_RESOURCE_LIST ResourceList = NULL; UINT ResourceListSize = 0; @@ -74,21 +130,40 @@ MiniportInitialize(OUT PNDIS_STATUS OpenErrorStatus, } /* Allocate our adapter context */ - Status = NdisAllocateMemoryWithTag((PVOID*)&Adapter, sizeof(*Adapter), B57XX_TAG); + Status = NdisAllocateMemoryWithTag((PVOID*)&Adapter, sizeof(B57XX_ADAPTER), B57XX_TAG); if (Status != NDIS_STATUS_SUCCESS) { NDIS_MinDbgPrint("Failed to allocate adapter context (0x%x)\n", Status); return NDIS_STATUS_RESOURCES; } - RtlZeroMemory(Adapter, sizeof(*Adapter)); + + NdisZeroMemory(Adapter, sizeof(*Adapter)); Adapter->MiniportAdapterHandle = MiniportAdapterHandle; + Adapter->HardwareStatus = NdisHardwareStatusNotReady; + NdisAllocateSpinLock(&Adapter->Interrupt.Lock); + NdisAllocateSpinLock(&Adapter->SendLock); + NdisAllocateSpinLock(&Adapter->InfoLock); /* Notify NDIS of some characteristics of our NIC */ - NdisMSetAttributesEx(MiniportAdapterHandle, + NdisMSetAttributesEx(Adapter->MiniportAdapterHandle, Adapter, 0, NDIS_ATTRIBUTE_BUS_MASTER, NdisInterfacePci); + + /* Get PCI configuration of our NIC */ + NdisReadPciSlotInformation(Adapter->MiniportAdapterHandle, + 0, + FIELD_OFFSET(PCI_COMMON_CONFIG, VendorID), + &PCIConfig, + sizeof(PCIConfig)); + Adapter->PciState.VendorID = PCIConfig.VendorID; + Adapter->PciState.DeviceID = PCIConfig.DeviceID; + Adapter->PciState.Command = PCIConfig.Command; + Adapter->PciState.CacheLineSize = PCIConfig.CacheLineSize; + Adapter->PciState.RevisionID = PCIConfig.RevisionID; + Adapter->PciState.SubVendorID = PCIConfig.u.type0.SubVendorID; + Adapter->PciState.SubSystemID = PCIConfig.u.type0.SubSystemID; /* Get our resources for IRQ and IO base information */ NdisMQueryAdapterResources(&Status, @@ -123,82 +198,170 @@ MiniportInitialize(OUT PNDIS_STATUS OpenErrorStatus, ASSERT(ResourceList->Revision == 1); /* Begin hardware initialization */ - Status = NICInitializeAdapterResources(Adapter, ResourceList); + Status = InitAdapterResources(Adapter, ResourceList); if (Status != NDIS_STATUS_SUCCESS) { - NDIS_MinDbgPrint("Adapter didn't receive enough resources\n"); goto Cleanup; } NdisFreeMemory(ResourceList, ResourceListSize, 0); ResourceList = NULL; + Status = NICConfigureAdapter(Adapter); + if (Status != NDIS_STATUS_SUCCESS) + { + goto Cleanup; + } + + /* Map physical IO address */ + Status = NdisMMapIoSpace((PVOID*)&Adapter->IoBase, + Adapter->MiniportAdapterHandle, + Adapter->IoAddress, + Adapter->IoLength); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_MinDbgPrint("Unable to map IO memory (0x%x)\n", Status); + return Status; + } + /* Allocate the DMA resources */ - Status = NdisMInitializeScatterGatherDma(MiniportAdapterHandle, FALSE, MAXIMUM_FRAME_SIZE); + Status = NdisMInitializeScatterGatherDma(MiniportAdapterHandle, + FALSE, + Adapter->MaxFrameSize); if (Status != NDIS_STATUS_SUCCESS) { NDIS_MinDbgPrint("Unable to configure DMA\n"); Status = NDIS_STATUS_RESOURCES; goto Cleanup; } - - Status = NICAllocateIoResources(Adapter); + + /* Allocate standard receive producer ring & buffer */ + Status = InitAllocateSharedMemory(Adapter, + sizeof(B57XX_RECEIVE_BUFFER_DESCRIPTOR) * + Adapter->StandardProducer.Count, + (PVOID*)&Adapter->StandardProducer.pRing, + &Adapter->StandardProducer.RingControlBlock.HostRingAddress); if (Status != NDIS_STATUS_SUCCESS) { - NDIS_MinDbgPrint("Unable to allocate resources\n"); - Status = NDIS_STATUS_RESOURCES; + NDIS_MinDbgPrint("Unable to allocate standard receive consumer ring"); goto Cleanup; } - - /* Adapter setup */ - Status = NICPowerOn(Adapter); + + Status = InitAllocateSharedMemory(Adapter, + Adapter->StandardProducer.FrameBufferLength * + Adapter->StandardProducer.Count, + (PVOID*)&Adapter->StandardProducer.HostBuffer, + &Adapter->StandardProducer.pRing[0].HostAddress); if (Status != NDIS_STATUS_SUCCESS) { - NDIS_MinDbgPrint("Unable to power on NIC (0x%x)\n", Status); + NDIS_MinDbgPrint("Unable to allocate host receive buffers"); goto Cleanup; } - - Status = NICSoftReset(Adapter); + + for (i = 0; i < Adapter->StandardProducer.Count; i++) + { + if (i != 0) + { + NdisMoveMemory(&Adapter->StandardProducer.pRing[i].HostAddress, + &Adapter->StandardProducer.pRing[0].HostAddress, + sizeof(B57XX_PHYSICAL_ADDRESS)); + B57XXAccumulateAddress(&Adapter->StandardProducer.pRing[i].HostAddress, + i * Adapter->StandardProducer.FrameBufferLength); + } + Adapter->StandardProducer.pRing[i].Index = i; + Adapter->StandardProducer.pRing[i].Length = Adapter->StandardProducer.FrameBufferLength; + Adapter->StandardProducer.pRing[i].Flags = B57XX_RBD_PACKET_END; + } + + /* Allocate receive return consumer ring */ + Status = InitAllocateSharedMemory(Adapter, + sizeof(B57XX_RECEIVE_BUFFER_DESCRIPTOR) * + Adapter->ReturnConsumer[0].Count, + (PVOID*)&Adapter->ReturnConsumer[0].pRing, + &Adapter->ReturnConsumer[0].RingControlBlock.HostRingAddress); if (Status != NDIS_STATUS_SUCCESS) { - NDIS_MinDbgPrint("Unable to reset the NIC (0x%x)\n", Status); + NDIS_MinDbgPrint("Unable to allocate receive return ring"); goto Cleanup; } - - Status = NICGetPermanentMacAddress(Adapter, Adapter->PermanentMacAddress); + + /* Allocate send producer ring & packet list */ + Status = InitAllocateSharedMemory(Adapter, + sizeof(B57XX_SEND_BUFFER_DESCRIPTOR) * + Adapter->SendProducer[0].Count, + (PVOID*)&Adapter->SendProducer[0].pRing, + &Adapter->SendProducer[0].RingControlBlock.HostRingAddress); if (Status != NDIS_STATUS_SUCCESS) { - NDIS_MinDbgPrint("Unable to get the fixed MAC address (0x%x)\n", Status); + NDIS_MinDbgPrint("Unable to allocate send ring"); goto Cleanup; } - - RtlCopyMemory(Adapter->MulticastList[0].MacAddress, - Adapter->PermanentMacAddress, - IEEE_802_ADDR_LENGTH); - NICUpdateMulticastList(Adapter); - - /* Update link state and speed */ - NICUpdateLinkStatus(Adapter); - - /* We're ready to handle interrupts now */ - Status = NICRegisterInterrupts(Adapter); + + Status = NdisAllocateMemoryWithTag((PVOID*)&Adapter->SendProducer[0].pPacketList, + sizeof(PNDIS_PACKET) * Adapter->SendProducer[0].Count, + B57XX_TAG); if (Status != NDIS_STATUS_SUCCESS) { - NDIS_MinDbgPrint("Unable to register interrupt (0x%x)\n", Status); + NDIS_MinDbgPrint("Unable to allocate transmit packet pointer list"); + goto Cleanup; + } + NdisZeroMemory(Adapter->SendProducer[0].pPacketList, + sizeof(PNDIS_PACKET) * Adapter->SendProducer[0].Count); + + /* Allocate status block */ + NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, + sizeof(B57XX_STATUS_BLOCK), + FALSE, + (PVOID*)&Adapter->Status.pBlock, + &Adapter->Status.HostAddress); + if (Adapter->Status.pBlock == NULL) + { + NDIS_MinDbgPrint("Unable to allocate status block"); + goto Cleanup; + } + NdisZeroMemory(Adapter->Status.pBlock, sizeof(B57XX_STATUS_BLOCK)); + + /* Allocate statistics block */ + if (!Adapter->B5705Plus) + { + NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, + sizeof(B57XX_STATISTICS_BLOCK), + FALSE, + (PVOID*)&Adapter->Statistics.pBlock, + &Adapter->Statistics.HostAddress); + if (Adapter->Statistics.pBlock == NULL) + { + NDIS_MinDbgPrint("Unable to allocate statistics block"); + goto Cleanup; + } + NdisZeroMemory(Adapter->Statistics.pBlock, sizeof(B57XX_STATISTICS_BLOCK)); + } + + /* Adapter setup */ + Status = NICPowerOn(Adapter); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_MinDbgPrint("Unable to power on NIC (0x%x)\n", Status); goto Cleanup; } - /* Enable interrupts on the NIC */ - Adapter->InterruptMask = DEFAULT_INTERRUPT_MASK; - NICApplyInterruptMask(Adapter); - - /* Turn on TX and RX now */ - Status = NICEnableTxRx(Adapter); + /* We're ready to handle interrupts now */ + Status = NdisMRegisterInterrupt(&Adapter->Interrupt.Interrupt, + Adapter->MiniportAdapterHandle, + Adapter->Interrupt.Vector, + Adapter->Interrupt.Level, + TRUE, // We always want ISR calls + Adapter->Interrupt.Shared, + (Adapter->Interrupt.Flags & CM_RESOURCE_INTERRUPT_LATCHED) ? + NdisInterruptLatched : NdisInterruptLevelSensitive); if (Status != NDIS_STATUS_SUCCESS) { - NDIS_MinDbgPrint("Unable to enable TX and RX (0x%x)\n", Status); + NDIS_MinDbgPrint("Unable to register interrupt (0x%x)\n", Status); goto Cleanup; } + Adapter->Interrupt.Registered = TRUE; + + NICEnableInterrupts(Adapter); return NDIS_STATUS_SUCCESS; @@ -213,20 +376,156 @@ MiniportInitialize(OUT PNDIS_STATUS OpenErrorStatus, return Status; } +NDIS_STATUS +NTAPI +MiniportReset(_Out_ PBOOLEAN AddressingReset, + _In_ NDIS_HANDLE MiniportAdapterContext) +{ + NDIS_STATUS Status; + PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; + + NDIS_MinDbgPrint("B57XX Reset\n"); + + *AddressingReset = TRUE; + + Status = NICSoftReset(Adapter); + if (Status == NDIS_STATUS_SUCCESS) + { + NICEnableInterrupts(Adapter); + } + + return Status; +} + +VOID +NTAPI +MiniportHalt(_In_ NDIS_HANDLE MiniportAdapterContext) +{ + PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; + + NDIS_MinDbgPrint("B57XX Halt\n"); + + ASSERT(Adapter != NULL); + + Adapter->HardwareStatus = NdisHardwareStatusNotReady; + + /* Unregister interrupts */ + if (Adapter->Interrupt.Registered) + { + NICDisableInterrupts(Adapter); + NdisMDeregisterInterrupt(&Adapter->Interrupt.Interrupt); + Adapter->Interrupt.Registered = FALSE; + } + + NICShutdown(Adapter); + + /* Free shared resources */ + FreeSharedMemory(Adapter, + Adapter->StandardProducer.FrameBufferLength * Adapter->StandardProducer.Count, + (PVOID)Adapter->StandardProducer.HostBuffer, + &Adapter->StandardProducer.pRing[0].HostAddress); + + FreeSharedMemory(Adapter, + sizeof(B57XX_RECEIVE_BUFFER_DESCRIPTOR) * Adapter->StandardProducer.Count, + (PVOID)Adapter->StandardProducer.pRing, + &Adapter->StandardProducer.RingControlBlock.HostRingAddress); + + FreeSharedMemory(Adapter, + sizeof(B57XX_RECEIVE_BUFFER_DESCRIPTOR) * Adapter->ReturnConsumer[0].Count, + (PVOID)Adapter->ReturnConsumer[0].pRing, + &Adapter->ReturnConsumer[0].RingControlBlock.HostRingAddress); + + FreeSharedMemory(Adapter, + sizeof(B57XX_SEND_BUFFER_DESCRIPTOR) * Adapter->SendProducer[0].Count, + (PVOID)Adapter->SendProducer[0].pRing, + &Adapter->SendProducer[0].RingControlBlock.HostRingAddress); + + if (Adapter->SendProducer[0].pPacketList != NULL) + { + NdisFreeMemory(Adapter->SendProducer[0].pPacketList, + sizeof(PNDIS_PACKET) * Adapter->SendProducer[0].Count, + 0); + } + + if (Adapter->Status.pBlock != NULL) + { + NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, + sizeof(B57XX_STATUS_BLOCK), + FALSE, + (PVOID)Adapter->Status.pBlock, + Adapter->Status.HostAddress); + } + + if (Adapter->Statistics.pBlock != NULL) + { + NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, + sizeof(B57XX_STATISTICS_BLOCK), + FALSE, + (PVOID)Adapter->Statistics.pBlock, + Adapter->Statistics.HostAddress); + } + + /* Free MMIO */ + if (Adapter->IoBase) + { + NdisMUnmapIoSpace(Adapter->MiniportAdapterHandle, Adapter->IoBase, Adapter->IoLength); + } + + /* Destroy the adapter context */ + NdisFreeMemory(Adapter, sizeof(B57XX_ADAPTER), 0); +} + +NDIS_STATUS +NTAPI +MiniportSend(_In_ NDIS_HANDLE MiniportAdapterContext, + _In_ PNDIS_PACKET Packet, + _In_ UINT Flags) +{ + NDIS_STATUS Status; + PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; + PSCATTER_GATHER_LIST SGList = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, + ScatterGatherListPacketInfo); + + + NdisAcquireSpinLock(&Adapter->SendLock); + + ASSERT(SGList != NULL); + + for (UINT i = 0; i < SGList->NumberOfElements; i++) + { + ASSERT(SGList->Elements[i].Length <= Adapter->MaxFrameSize); + + Adapter->SendProducer[0].pPacketList[Adapter->SendProducer[0].ProducerIndex] = Packet; + + Status = NICTransmitPacket(Adapter, + SGList->Elements[i].Address, + SGList->Elements[i].Length, + i == SGList->NumberOfElements - 1 ? B57XX_SBD_PACKET_END : 0); + if (Status != NDIS_STATUS_SUCCESS) + { + Adapter->Statistics.TransmitErrors++; + } + } + + NdisReleaseSpinLock(&Adapter->SendLock); + + return NDIS_STATUS_PENDING; +} + NTSTATUS NTAPI -DriverEntry(IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath) +DriverEntry(_In_ PDRIVER_OBJECT DriverObject, + _In_ PUNICODE_STRING RegistryPath) { NDIS_HANDLE WrapperHandle; - NDIS_MINIPORT_CHARACTERISTICS Characteristics = {0}; NDIS_STATUS Status; + NDIS_MINIPORT_CHARACTERISTICS Characteristics = {0}; Characteristics.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION; Characteristics.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION; Characteristics.CheckForHangHandler = NULL; - Characteristics.DisableInterruptHandler = NULL; - Characteristics.EnableInterruptHandler = NULL; + Characteristics.DisableInterruptHandler = MiniportDisableInterrupt; + Characteristics.EnableInterruptHandler = MiniportEnableInterrupt; Characteristics.HaltHandler = MiniportHalt; Characteristics.HandleInterruptHandler = MiniportHandleInterrupt; Characteristics.InitializeHandler = MiniportInitialize; @@ -237,9 +536,9 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject, Characteristics.SendHandler = MiniportSend; Characteristics.SetInformationHandler = MiniportSetInformation; Characteristics.TransferDataHandler = NULL; - Characteristics.ReturnPacketHandler = NULL; + /*Characteristics.ReturnPacketHandler = NULL; Characteristics.SendPacketsHandler = NULL; - Characteristics.AllocateCompleteHandler = NULL; + Characteristics.AllocateCompleteHandler = NULL;*/ NdisMInitializeWrapper(&WrapperHandle, DriverObject, RegistryPath, NULL); if (!WrapperHandle) @@ -251,7 +550,7 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject, if (Status != NDIS_STATUS_SUCCESS) { NdisTerminateWrapper(WrapperHandle, 0); - return NDIS_STATUS_FAILURE; + return Status; } return NDIS_STATUS_SUCCESS; diff --git a/drivers/network/dd/b57xx/netb57xx.inf b/drivers/network/dd/b57xx/netb57xx.inf index 0b1a97abab880..22ec511c01d3f 100644 --- a/drivers/network/dd/b57xx/netb57xx.inf +++ b/drivers/network/dd/b57xx/netb57xx.inf @@ -7,7 +7,7 @@ LayoutFile = layout.inf Class = Net ClassGUID = {4D36E972-E325-11CE-BFC1-08002BE10318} Provider = %ReactOS% -DriverVer = 12/24/2021,1.00 +DriverVer = 02/04/2022,1.00 [DestinationDirs] DefaultDestDir = 12 @@ -16,29 +16,79 @@ DefaultDestDir = 12 %BroadcomMfg% = BroadcomMfg [BroadcomMfg] -%Broadcom5752.DeviceDesc% = B57XX_Inst.ndi,PCI\VEN_14E4&DEV_1600 -; %Broadcom5752M.DeviceDesc% = B57XX_Inst.ndi,PCI\VEN_14E4&DEV_1601 +%Broadcom5700.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1644 +%Broadcom5701.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1645 +%Broadcom5702.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_16A6 +%Broadcom5702.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1646 +%Broadcom5702.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_16C6 +%Broadcom5703C.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_16C7 +%Broadcom5703C.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1647 +%Broadcom5703C.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_16A7 +%Broadcom5703S.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_16C7&SUBSYS_000A14E4 +%Broadcom5703S.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1647&SUBSYS_000A14E4 +%Broadcom5703S.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_16A7&SUBSYS_000A14E4 +%Broadcom5704C.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1648 +%Broadcom5704S.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_16A8 +%Broadcom5704S.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_16A8 +%Broadcom5705.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1653 +%Broadcom5705.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1654 +%Broadcom5705M.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_165D +%Broadcom5705M.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_165E +%Broadcom5721.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1659 +%Broadcom5751.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1677 +%Broadcom5751M.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_167D +%Broadcom5752.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1600 +%Broadcom5752M.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1601 +%Broadcom5714C.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1668 +%Broadcom5714S.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1669 +%Broadcom5715C.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1678 +%Broadcom5715S.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1679 +%Broadcom5722.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_165A +%Broadcom5755.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_167B +%Broadcom5755M.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1673 +%Broadcom5754.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_167A +%Broadcom5754M.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1672 +%Broadcom5756M.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1674 +%Broadcom5757.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1670 +%Broadcom5786.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_169A +%Broadcom5787.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_169B +%Broadcom5787M.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1693 +%Broadcom5784M.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1698 +%Broadcom5764M.DeviceDesc% = B57XX.Inst.ndi,PCI\VEN_14E4&DEV_1684 ;----------------------------- B57XX DRIVER ----------------------------- -[B57XX_Inst.ndi.NT] +[B57XX.Inst.ndi.NT] Characteristics = 0x4 ; NCF_PHYSICAL BusType = 5 ; PCIBus -CopyFiles = B57XX_CopyFiles.NT +CopyFiles = B57XX.Inst.CopyFiles +AddReg = B57XX.Inst.AddReg -[B57XX_CopyFiles.NT] +[B57XX.Inst.CopyFiles] b57xx.sys -[B57XX_Inst.ndi.NT.Services] -AddService = b57xx, 0x00000002, B57XX_Service_Inst +[B57XX.Inst.ndi.NT.Services] +AddService = b57xx, 0x00000002, B57XX.Inst.AddService, B57XX.Inst.AddEventLog -[B57XX_Service_Inst] -ServiceType = 1 -StartType = 3 -ErrorControl = 0 -ServiceBinary = %12%\b57xx.sys +[B57XX.Inst.AddService] +ServiceType = 1 +StartType = 3 +ErrorControl = 1 +ServiceBinary = %12%\b57xx.sys LoadOrderGroup = NDIS +[B57XX.Inst.AddEventLog] +AddReg = B57XX.Inst.AddEventLog.AddReg + +[B57XX.Inst.AddReg] +HKR, Ndi, Service, 0, "b57xx" +HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" +HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" + +[B57XX.Inst.AddEventLog.AddReg] +HKR, , EventMessageFile, 0x00020000, "%%SystemRoot%%\System32\netevent.dll;%%SystemRoot%%\System32\drivers\b57xx.sys" +HKR, , TypesSupported , 0x00010001, 7 + ;-------------------------------- STRINGS ------------------------------- [Strings] @@ -46,4 +96,34 @@ ReactOS = "ReactOS Team" BroadcomMfg = "Broadcom" -Broadcom5752.DeviceDesc = "Broadcom NetXtreme 5752 Gigabit Controller" +Broadcom5700.DeviceDesc = "Broadcom NetXtreme 5700 Gigabit Ethernet MAC" +Broadcom5701.DeviceDesc = "Broadcom NetXtreme 5701 Gigabit Ethernet Adapter" +Broadcom5702.DeviceDesc = "Broadcom NetXtreme 5702 Gigabit Ethernet Adapter" +Broadcom5703C.DeviceDesc = "Broadcom NetXtreme 5703C Gigabit Ethernet Adapter" +Broadcom5703S.DeviceDesc = "Broadcom NetXtreme 5703S Gigabit Fiber Adapter" +Broadcom5704C.DeviceDesc = "Broadcom NetXtreme 5704C Gigabit Ethernet Adapter" +Broadcom5704S.DeviceDesc = "Broadcom NetXtreme 5705S Gigabit Fiber Adapter" +Broadcom5705.DeviceDesc = "Broadcom NetXtreme 5705 Gigabit Ethernet Adapter" +Broadcom5705M.DeviceDesc = "Broadcom NetXtreme 5705M Gigabit Ethernet Adapter" +Broadcom5788.DeviceDesc = "Broadcom NetXtreme 5788 Gigabit Ethernet Adapter" +Broadcom5721.DeviceDesc = "Broadcom NetXtreme 5721 Gigabit Ethernet Adapter" +Broadcom5751.DeviceDesc = "Broadcom NetXtreme 5751 Gigabit Ethernet Adapter" +Broadcom5751M.DeviceDesc = "Broadcom NetXtreme 5751M Gigabit Ethernet Adapter" +Broadcom5752.DeviceDesc = "Broadcom NetXtreme 5752 Gigabit Ethernet Adapter" +Broadcom5752M.DeviceDesc = "Broadcom NetXtreme 5752M Gigabit Ethernet Adapter" +Broadcom5714C.DeviceDesc = "Broadcom NetXtreme 5714C Gigabit Ethernet Adapter" +Broadcom5714S.DeviceDesc = "Broadcom NetXtreme 5714S Gigabit Fiber Adapter" +Broadcom5715C.DeviceDesc = "Broadcom NetXtreme 5715C Gigabit Ethernet Adapter" +Broadcom5715S.DeviceDesc = "Broadcom NetXtreme 5715S Gigabit Fiber Adapter" +Broadcom5722.DeviceDesc = "Broadcom NetXtreme 5722 Gigabit Ethernet Adapter" +Broadcom5755.DeviceDesc = "Broadcom NetXtreme 5755 Gigabit Ethernet Adapter" +Broadcom5755M.DeviceDesc = "Broadcom NetXtreme 5755M Gigabit Ethernet Adapter" +Broadcom5754.DeviceDesc = "Broadcom NetXtreme 5754 Gigabit Ethernet Adapter" +Broadcom5754M.DeviceDesc = "Broadcom NetXtreme 5754M Gigabit Ethernet Adapter" +Broadcom5756M.DeviceDesc = "Broadcom NetXtreme 5756M Gigabit Ethernet Adapter" +Broadcom5757.DeviceDesc = "Broadcom NetXtreme 5757 Gigabit Ethernet Adapter" +Broadcom5786.DeviceDesc = "Broadcom NetXtreme 5786 Gigabit Ethernet Adapter" +Broadcom5787.DeviceDesc = "Broadcom NetXtreme 5787 Gigabit Ethernet Adapter" +Broadcom5787M.DeviceDesc = "Broadcom NetXtreme 5787M Gigabit Ethernet Adapter" +Broadcom5784M.DeviceDesc = "Broadcom NetXtreme 5784M Gigabit Ethernet Adapter" +Broadcom5764M.DeviceDesc = "Broadcom NetXtreme 5764M Gigabit Ethernet Adapter" diff --git a/drivers/network/dd/b57xx/nic.h b/drivers/network/dd/b57xx/nic.h index bf6badba5e94d..121f91fa1a3e4 100644 --- a/drivers/network/dd/b57xx/nic.h +++ b/drivers/network/dd/b57xx/nic.h @@ -2,7 +2,7 @@ * PROJECT: ReactOS Broadcom NetXtreme Driver * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: Hardware driver definitions - * COPYRIGHT: Copyright 2021 Scott Maday + * COPYRIGHT: Copyright 2021-2022 Scott Maday */ #pragma once @@ -10,225 +10,447 @@ #include "b57xxhw.h" -#define B57XX_TAG '075b' +#define B57XX_TAG '075b' +#define DRIVER_VERSION 1 -#define MAXIMUM_FRAME_SIZE 1522 -#define RECEIVE_BUFFER_SIZE 2048 - -#define DRIVER_VERSION 1 - -#define DEFAULT_INTERRUPT_MASK 0 +#define PAYLOAD_SIZE_MINI 500 +#define PAYLOAD_SIZE_STANDARD 1500 +#define PAYLOAD_SIZE_JUMBO 9000 typedef struct _B57XX_ADAPTER { /* NIC Memory */ NDIS_HANDLE MiniportAdapterHandle; + NDIS_HARDWARE_STATUS HardwareStatus; volatile PUCHAR IoBase; NDIS_PHYSICAL_ADDRESS IoAddress; ULONG IoLength; - - UCHAR PermanentMacAddress[IEEE_802_ADDR_LENGTH]; - struct { - UCHAR MacAddress[IEEE_802_ADDR_LENGTH]; - } MulticastList[MAXIMUM_MULTICAST_ADDRESSES]; + B57XX_DEVICE_ID DeviceID; + BOOLEAN B5705Plus; + BOOLEAN B5721Plus; + BOOLEAN IsSerDes; + + struct _B57XX_PCI_STATE + { + USHORT VendorID; + USHORT DeviceID; + USHORT Command; + UCHAR CacheLineSize; + USHORT SubVendorID; + USHORT SubSystemID; + UCHAR RevisionID; + } PciState; + + struct _B57XX_INTERRUPT + { + ULONG Vector; + ULONG Level; + BOOLEAN Shared; + ULONG Flags; + NDIS_MINIPORT_INTERRUPT Interrupt; + BOOLEAN Registered; + BOOLEAN Pending; + NDIS_SPIN_LOCK Lock; + } Interrupt; + + /* RX */ + B57XX_RECEIVE_PRODUCER_BLOCK MiniProducer; + B57XX_RECEIVE_PRODUCER_BLOCK StandardProducer; + B57XX_RECEIVE_PRODUCER_BLOCK JumboProducer; + B57XX_RECEIVE_CONSUMER_BLOCK ReturnConsumer[1]; + + /* TX */ + B57XX_SEND_BLOCK SendProducer[1]; + NDIS_SPIN_LOCK SendLock; + + /* Status */ + struct _B57XX_STATUS + { + PB57XX_STATUS_BLOCK pBlock; + NDIS_PHYSICAL_ADDRESS HostAddress; + ULONG LastTag; + } Status; + + /* Statistics */ + struct _B57XX_STATISTICS + { + PB57XX_STATISTICS_BLOCK pBlock; + NDIS_PHYSICAL_ADDRESS HostAddress; + ULONG64 TransmitSuccesses; + ULONG64 ReceiveSuccesses; + ULONG64 TransmitErrors; + ULONG64 ReceiveErrors; + ULONG64 ReceiveBufferErrors; + } Statistics; + + /* NIC Info */ + ULONG MaxFrameSize; + MAC_ADDRESS MACAddresses[1]; + MAC_ADDRESS MulticastList[MAXIMUM_MULTICAST_ADDRESSES]; ULONG MulticastListSize; - - ULONG LinkSpeedMbps; - ULONG MediaState; + + NDIS_SPIN_LOCK InfoLock; ULONG PacketFilter; - - /* Io Port */ - ULONG IoPortAddress; - ULONG IoPortLength; - volatile PUCHAR IoPort; - - /* Interrupt */ - ULONG InterruptVector; - ULONG InterruptLevel; - BOOLEAN InterruptShared; - ULONG InterruptFlags; - - NDIS_MINIPORT_INTERRUPT Interrupt; - BOOLEAN InterruptRegistered; - - LONG InterruptMask; + USHORT LinkStatus; } B57XX_ADAPTER, *PB57XX_ADAPTER; +/* MINIPORT FUNCTIONS *****************************************************************************/ -/* MINIPORT FUNCTIONS *********************************************************/ +NDIS_STATUS +NTAPI +MiniportInitialize(_Out_ PNDIS_STATUS OpenErrorStatus, + _Out_ PUINT SelectedMediumIndex, + _In_ PNDIS_MEDIUM MediumArray, + _In_ UINT MediumArraySize, + _In_ NDIS_HANDLE MiniportAdapterHandle, + _In_ NDIS_HANDLE WrapperConfigurationContext); + +NDIS_STATUS +NTAPI +MiniportReset(_Out_ PBOOLEAN AddressingReset, + _In_ NDIS_HANDLE MiniportAdapterContext); VOID NTAPI -MiniportHalt(IN NDIS_HANDLE MiniportAdapterContext); +MiniportHalt(_In_ NDIS_HANDLE MiniportAdapterContext); NDIS_STATUS NTAPI -MiniportInitialize(OUT PNDIS_STATUS OpenErrorStatus, - OUT PUINT SelectedMediumIndex, - IN PNDIS_MEDIUM MediumArray, - IN UINT MediumArraySize, - IN NDIS_HANDLE MiniportAdapterHandle, - IN NDIS_HANDLE WrapperConfigurationContext); +MiniportSend(_In_ NDIS_HANDLE MiniportAdapterContext, + _In_ PNDIS_PACKET Packet, + _In_ UINT Flags); NDIS_STATUS NTAPI -MiniportSetInformation(IN NDIS_HANDLE MiniportAdapterContext, - IN NDIS_OID Oid, - IN PVOID InformationBuffer, - IN ULONG InformationBufferLength, - OUT PULONG BytesRead, - OUT PULONG BytesNeeded); +MiniportSetInformation(_In_ NDIS_HANDLE MiniportAdapterContext, + _In_ NDIS_OID Oid, + _In_ PVOID InformationBuffer, + _In_ ULONG InformationBufferLength, + _Out_ PULONG BytesRead, + _Out_ PULONG BytesNeeded); NDIS_STATUS NTAPI -MiniportQueryInformation(IN NDIS_HANDLE MiniportAdapterContext, - IN NDIS_OID Oid, - IN PVOID InformationBuffer, - IN ULONG InformationBufferLength, - OUT PULONG BytesWritten, - OUT PULONG BytesNeeded); +MiniportQueryInformation(_In_ NDIS_HANDLE MiniportAdapterContext, + _In_ NDIS_OID Oid, + _In_ PVOID InformationBuffer, + _In_ ULONG InformationBufferLength, + _Out_ PULONG BytesWritten, + _Out_ PULONG BytesNeeded); -NDIS_STATUS +VOID NTAPI -MiniportSetInformation(IN NDIS_HANDLE MiniportAdapterContext, - IN NDIS_OID Oid, - IN PVOID InformationBuffer, - IN ULONG InformationBufferLength, - OUT PULONG BytesRead, - OUT PULONG BytesNeeded); - +MiniportDisableInterrupt(_In_ NDIS_HANDLE MiniportAdapterContext); VOID NTAPI -MiniportISR(OUT PBOOLEAN InterruptRecognized, - OUT PBOOLEAN QueueMiniportHandleInterrupt, - IN NDIS_HANDLE MiniportAdapterContext); +MiniportEnableInterrupt(_In_ NDIS_HANDLE MiniportAdapterContext); + VOID NTAPI -MiniportHandleInterrupt(IN NDIS_HANDLE MiniportAdapterContext); +MiniportISR(_Out_ PBOOLEAN InterruptRecognized, + _Out_ PBOOLEAN QueueMiniportHandleInterrupt, + _In_ NDIS_HANDLE MiniportAdapterContext); -NDIS_STATUS +VOID NTAPI -MiniportSend(IN NDIS_HANDLE MiniportAdapterContext, - IN PNDIS_PACKET Packet, - IN UINT Flags); +MiniportHandleInterrupt(_In_ NDIS_HANDLE MiniportAdapterContext); +/* NIC FUNCTIONS **********************************************************************************/ -/* NIC FUNCTIONS **************************************************************/ +#define NICISDEVICE(Adapter, ...) \ + NICIsDevice(Adapter, \ + sizeof((B57XX_DEVICE_ID[]){__VA_ARGS__})/sizeof(B57XX_DEVICE_ID), \ + (B57XX_DEVICE_ID[]){__VA_ARGS__}) BOOLEAN NTAPI -NICRecognizeHardware(IN PB57XX_ADAPTER Adapter); +NICIsDevice(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG DeviceIDListLength, + _In_reads_(DeviceIDListLength) const B57XX_DEVICE_ID DeviceIDList[]); +_Check_return_ NDIS_STATUS NTAPI -NICInitializeAdapterResources(IN PB57XX_ADAPTER Adapter, - IN PNDIS_RESOURCE_LIST ResourceList); +NICConfigureAdapter(_In_ PB57XX_ADAPTER Adapter); +_Check_return_ NDIS_STATUS NTAPI -NICAllocateIoResources(IN PB57XX_ADAPTER Adapter); +NICPowerOn(_In_ PB57XX_ADAPTER Adapter); +_Check_return_ NDIS_STATUS NTAPI -NICRegisterInterrupts(IN PB57XX_ADAPTER Adapter); +NICSoftReset(_In_ PB57XX_ADAPTER Adapter); NDIS_STATUS NTAPI -NICUnregisterInterrupts(IN PB57XX_ADAPTER Adapter); +NICSetupPHY(_In_ PB57XX_ADAPTER Adapter); NDIS_STATUS NTAPI -NICReleaseIoResources(IN PB57XX_ADAPTER Adapter); +NICUpdateLinkStatus(_In_ PB57XX_ADAPTER Adapter); -NDIS_STATUS +VOID NTAPI -NICPowerOn(IN PB57XX_ADAPTER Adapter); +NICSetupFlowControl(_In_ PB57XX_ADAPTER Adapter); NDIS_STATUS NTAPI -NICSoftReset(IN PB57XX_ADAPTER Adapter); +NICShutdown(_In_ PB57XX_ADAPTER Adapter); -NDIS_STATUS +VOID NTAPI -NICEnableTxRx(IN PB57XX_ADAPTER Adapter); +NICUpdateMACAddresses(_In_ PB57XX_ADAPTER Adapter); NDIS_STATUS NTAPI -NICDisableTxRx(IN PB57XX_ADAPTER Adapter); +NICUpdateMulticastList(_In_ PB57XX_ADAPTER Adapter); NDIS_STATUS NTAPI -NICGetPermanentMacAddress(IN PB57XX_ADAPTER Adapter, - OUT PUCHAR MacAddress); +NICApplyPacketFilter(_In_ PB57XX_ADAPTER Adapter); +_Check_return_ NDIS_STATUS NTAPI -NICUpdateMulticastList(IN PB57XX_ADAPTER Adapter); +NICTransmitPacket(_In_ PB57XX_ADAPTER Adapter, + _In_ PHYSICAL_ADDRESS PhysicalAddress, + _In_ ULONG Length, + _In_ USHORT Flags); -NDIS_STATUS +VOID +NTAPI +NICEnableInterrupts(_In_ PB57XX_ADAPTER Adapter); + +VOID +NTAPI +NICDisableInterrupts(_In_ PB57XX_ADAPTER Adapter); + +VOID NTAPI -NICApplyPacketFilter(IN PB57XX_ADAPTER Adapter); +NICInterruptAcknowledge(_In_ PB57XX_ADAPTER Adapter); + +BOOLEAN +NTAPI +NICInterruptCheckAvailability(_In_ PB57XX_ADAPTER Adapter); VOID NTAPI -NICUpdateLinkStatus(IN PB57XX_ADAPTER Adapter); +NICInterruptSignalComplete(_In_ PB57XX_ADAPTER Adapter); + +VOID +NTAPI +NICReceiveSignalComplete(_In_ PB57XX_ADAPTER Adapter); + +VOID +NTAPI +NICQueryStatisticCounter(_In_ PB57XX_ADAPTER Adapter, + _In_ NDIS_OID Oid, + _Out_ PULONG64 pValue64); NDIS_STATUS NTAPI -NICTransmitPacket(IN PB57XX_ADAPTER Adapter, - IN PHYSICAL_ADDRESS PhysicalAddress, - IN ULONG Length); +NICFillPowerManagementCapabilities(_In_ PB57XX_ADAPTER Adapter, + _Out_ PNDIS_PNP_CAPABILITIES Capabilities); -/* B57XX FUNCTIONS ************************************************************/ +VOID +NTAPI +NICOutputDebugInfo(_In_ PB57XX_ADAPTER Adapter); -BOOLEAN -B57XXReadEeprom(IN PB57XX_ADAPTER Adapter, - IN UCHAR Address, - USHORT *Result); +/* B57XX FUNCTIONS ********************************************************************************/ + +FORCEINLINE +ULONG +B57XXReadPciConfigULong(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Offset, + _Out_ PULONG pValue) +{ + return NdisReadPciSlotInformation(Adapter->MiniportAdapterHandle, + 0, + Offset, + (PVOID)pValue, + sizeof(ULONG)); +} + +FORCEINLINE +ULONG +B57XXWritePciConfigULong(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Offset, + _In_ ULONG Value) +{ + return NdisWritePciSlotInformation(Adapter->MiniportAdapterHandle, + 0, + Offset, + (PVOID)&Value, + sizeof(ULONG)); +} + +FORCEINLINE +VOID +B57XXEnableUShort(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Address, + _Inout_ PULONG pValue, + _In_ ULONG Mask) +{ + NdisReadRegisterUshort((PUSHORT)(Adapter->IoBase + Address), pValue); + *pValue |= Mask; + NdisWriteRegisterUshort((PUSHORT)(Adapter->IoBase + Address), *pValue); +} FORCEINLINE VOID -B57XXReadUlong(IN PB57XX_ADAPTER Adapter, - IN ULONG Address, - OUT PULONG Value) +B57XXReadULong(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Address, + _Out_ PULONG pValue) { - NdisReadRegisterUlong((PULONG)(Adapter->IoBase + Address), Value); + NdisReadRegisterUlong((PULONG)(Adapter->IoBase + Address), pValue); } FORCEINLINE VOID -B57XXWriteUlong(IN PB57XX_ADAPTER Adapter, - IN ULONG Address, - IN ULONG Value) +B57XXWriteULong(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Address, + _In_ ULONG Value) { NdisWriteRegisterUlong((PULONG)(Adapter->IoBase + Address), Value); } FORCEINLINE VOID -B57XXWriteIoUlong(IN PB57XX_ADAPTER Adapter, - IN ULONG Address, - IN ULONG Value) +B57XXEnableULong(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Address, + _Inout_ PULONG pValue, + _In_ ULONG Mask) +{ + B57XXReadULong(Adapter, Address, pValue); + *pValue |= Mask; + B57XXWriteULong(Adapter, Address, *pValue); +} + +FORCEINLINE +VOID +B57XXReadRegister(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Address, + _Out_ PULONG pValue) +{ + B57XXWritePciConfigULong(Adapter, B57XX_REG_REG_BASE, Address); + B57XXReadPciConfigULong(Adapter, B57XX_REG_REG_DATA, pValue); +} + +FORCEINLINE +VOID +B57XXWriteRegister(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Address, + _In_ ULONG Value) +{ + B57XXWritePciConfigULong(Adapter, B57XX_REG_REG_BASE, Address); + B57XXWritePciConfigULong(Adapter, B57XX_REG_REG_DATA, Value); + + B57XXWriteULong(Adapter, Address, Value); +} + +FORCEINLINE +VOID +B57XXEnableRegister(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Address, + _Inout_ PULONG pValue, + _In_ ULONG Mask) +{ + B57XXWritePciConfigULong(Adapter, B57XX_REG_REG_BASE, Address); + B57XXReadPciConfigULong(Adapter, B57XX_REG_REG_DATA, pValue); + *pValue |= Mask; + B57XXWritePciConfigULong(Adapter, B57XX_REG_REG_DATA, *pValue); +} + +FORCEINLINE +VOID +B57XXDisableRegister(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Address, + _Inout_ PULONG pValue, + _In_ ULONG Mask) { - //volatile ULONG Dummy; + B57XXWritePciConfigULong(Adapter, B57XX_REG_REG_BASE, Address); + B57XXReadPciConfigULong(Adapter, B57XX_REG_REG_DATA, pValue); + *pValue &= ~Mask; + B57XXWritePciConfigULong(Adapter, B57XX_REG_REG_DATA, *pValue); +} + +FORCEINLINE +VOID +B57XXWriteMailbox(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Address, + _In_ ULONG Value) +{ + B57XXWriteULong(Adapter, Address + 4, Value); +} - NdisRawWritePortUlong((PULONG)(Adapter->IoPort), Address); - //NdisReadRegisterUlong(Adapter->IoBase + B57XX_REG_STATUS, &Dummy); TODO - NdisRawWritePortUlong((PULONG)(Adapter->IoPort + 4), Value); +FORCEINLINE +VOID +B57XXReadMemoryULong(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Address, + _Out_ PULONG pValue) +{ + B57XXWritePciConfigULong(Adapter, B57XX_REG_MEM_BASE, Address); + B57XXReadPciConfigULong(Adapter, B57XX_REG_MEM_DATA, pValue); } FORCEINLINE VOID -NICApplyInterruptMask(IN PB57XX_ADAPTER Adapter) +B57XXWriteMemoryULong(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Address, + _In_ ULONG Value) { - //B57XXWriteUlong(Adapter, B57XX_REG_IMS, Adapter->InterruptMask); + B57XXWritePciConfigULong(Adapter, B57XX_REG_MEM_BASE, Address); + B57XXWritePciConfigULong(Adapter, B57XX_REG_MEM_DATA, Value); } FORCEINLINE VOID -NICDisableInterrupts(IN PB57XX_ADAPTER Adapter) +B57XXConvertAddress(_Out_ PB57XX_PHYSICAL_ADDRESS pDestination, + _In_ PNDIS_PHYSICAL_ADDRESS pAddress) { - //B57XXWriteUlong(Adapter, B57XX_REG_IMC, ~0); -} \ No newline at end of file + pDestination->HighPart = pAddress->HighPart; + pDestination->LowPart = pAddress->LowPart; +} + +VOID +B57XXWriteMemoryRCB(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG Address, + _In_ volatile PB57XX_RING_CONTROL_BLOCK pRCB); + +NDIS_STATUS +B57XXReadPHY(_In_ PB57XX_ADAPTER Adapter, + _In_ USHORT PHYRegOffset, + _Out_ PUSHORT pValue); + +NDIS_STATUS +B57XXWritePHY(_In_ PB57XX_ADAPTER Adapter, + _In_ USHORT PHYRegOffset, + _In_ USHORT Value); + +VOID +B57XXReadAndClearPHYInterrupts(_In_ PB57XX_ADAPTER Adapter, + _Out_ PUSHORT Interrupts); + +VOID +B57XXClearMACAttentions(_In_ PB57XX_ADAPTER Adapter); + +VOID +B57XXReadStatistic(_In_ PB57XX_ADAPTER Adapter, + _In_ ULONG BlockOffset, + _In_ ULONG RegOffset, + _In_ BOOLEAN Is64Bit, + _Out_ PULONG64 pValue64); + +VOID +B57XXAccumulateAddress(_Out_ PB57XX_PHYSICAL_ADDRESS pDestination, + _In_ LONG Offset); + +ULONG +B57XXComputeInverseCrc32(_In_ PUCHAR pBuffer, + _In_ ULONG BufferSize); + +/* EOF */ diff --git a/drivers/network/dd/b57xx/send.c b/drivers/network/dd/b57xx/send.c deleted file mode 100644 index 6c084700298a1..0000000000000 --- a/drivers/network/dd/b57xx/send.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * PROJECT: ReactOS Broadcom NetXtreme Driver - * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) - * PURPOSE: Sending packets - * COPYRIGHT: Copyright 2021 Scott Maday - */ - -#include "nic.h" - -#include - -NDIS_STATUS -NTAPI -NICTransmitPacket(IN PB57XX_ADAPTER Adapter, - IN PHYSICAL_ADDRESS PhysicalAddress, - IN ULONG Length) -{ - NDIS_MinDbgPrint("NICTransmitPacket\n"); - - return NDIS_STATUS_FAILURE; -} - - -NDIS_STATUS -NTAPI -MiniportSend(IN NDIS_HANDLE MiniportAdapterContext, - IN PNDIS_PACKET Packet, - IN UINT Flags) -{ - PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; - NDIS_STATUS Status; - PSCATTER_GATHER_LIST SGList; - ULONG TransmitLength; - PHYSICAL_ADDRESS TransmitBuffer; - - NDIS_MinDbgPrint("B57XX send\n"); - - SGList = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, ScatterGatherListPacketInfo); - - ASSERT(SGList != NULL); - ASSERT(SGList->NumberOfElements == 1); - ASSERT((SGList->Elements[0].Address.LowPart & 3) == 0); - ASSERT(SGList->Elements[0].Length <= MAXIMUM_FRAME_SIZE); - - /*if (Adapter->TxFull) - { - NDIS_MinDbgPrint("All TX descriptors are full\n"); - return NDIS_STATUS_RESOURCES; - }*/ - - TransmitLength = SGList->Elements[0].Length; - TransmitBuffer = SGList->Elements[0].Address; - //Adapter->TransmitPackets[Adapter->CurrentTxDesc] = Packet; TODO - - Status = NICTransmitPacket(Adapter, TransmitBuffer, TransmitLength); - if (Status != NDIS_STATUS_SUCCESS) - { - NDIS_MinDbgPrint("Transmit packet failed\n"); - return Status; - } - - return NDIS_STATUS_PENDING; -}