diff --git a/drivers/network/dd/CMakeLists.txt b/drivers/network/dd/CMakeLists.txt index 122b82823f721..61060fbc93be1 100644 --- a/drivers/network/dd/CMakeLists.txt +++ b/drivers/network/dd/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(dc21x4) +add_subdirectory(b57xx) add_subdirectory(e1000) add_subdirectory(ne2000) add_subdirectory(netkvm) diff --git a/drivers/network/dd/b57xx/CMakeLists.txt b/drivers/network/dd/b57xx/CMakeLists.txt new file mode 100644 index 0000000000000..32f00554708c6 --- /dev/null +++ b/drivers/network/dd/b57xx/CMakeLists.txt @@ -0,0 +1,20 @@ + +add_definitions( + -DNDIS50_MINIPORT + -DNDIS_MINIPORT_DRIVER + -DNDIS_LEGACY_MINIPORT) + +list(APPEND SOURCE + ndis.c + hardware.c + info.c + interrupt.c + nic.h + send.c) + +add_library(b57xx MODULE ${SOURCE} b57xx.rc) +add_pch(b57xx nic.h SOURCE) +set_module_type(b57xx kernelmodedriver) +add_importlibs(b57xx ndis ntoskrnl hal) +add_cd_file(TARGET b57xx DESTINATION reactos/system32/drivers FOR all) +add_driver_inf(b57xx netb57xx.inf) diff --git a/drivers/network/dd/b57xx/b57xx.rc b/drivers/network/dd/b57xx/b57xx.rc new file mode 100644 index 0000000000000..3c08a45807373 --- /dev/null +++ b/drivers/network/dd/b57xx/b57xx.rc @@ -0,0 +1,5 @@ +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Broadcom NetXtreme Driver" +#define REACTOS_STR_INTERNAL_NAME "b57xx" +#define REACTOS_STR_ORIGINAL_FILENAME "b57xx.sys" +#include diff --git a/drivers/network/dd/b57xx/b57xxhw.h b/drivers/network/dd/b57xx/b57xxhw.h new file mode 100644 index 0000000000000..4e9a4999bbab0 --- /dev/null +++ b/drivers/network/dd/b57xx/b57xxhw.h @@ -0,0 +1,22 @@ +/* + * 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 + */ +#pragma once + +#define IEEE_802_ADDR_LENGTH 6 + +#define MAX_RESET_ATTEMPTS 10 +#define MAX_EEPROM_READ_ATTEMPTS 10000 + +#define MAXIMUM_MULTICAST_ADDRESSES 16 + +/* Ethernet frame header */ +typedef struct _ETH_HEADER +{ + UCHAR Destination[IEEE_802_ADDR_LENGTH]; + UCHAR Source[IEEE_802_ADDR_LENGTH]; + USHORT PayloadType; +} ETH_HEADER, *PETH_HEADER; diff --git a/drivers/network/dd/b57xx/debug.h b/drivers/network/dd/b57xx/debug.h new file mode 100644 index 0000000000000..0afb2aa95c240 --- /dev/null +++ b/drivers/network/dd/b57xx/debug.h @@ -0,0 +1,92 @@ +/* + * PROJECT: ReactOS Broadcom NetXtreme Driver + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Debugging support macros + * DEFINES: DBG - Enable debug output + * NASSERT - Disable assertions + */ +#pragma once + +#define NORMAL_MASK 0x000000FF +#define SPECIAL_MASK 0xFFFFFF00 +#define MIN_TRACE 0x00000001 +#define MID_TRACE 0x00000002 +#define MAX_TRACE 0x00000003 + +#define DEBUG_MEMORY 0x00000100 +#define DEBUG_ULTRA 0xFFFFFFFF + +#if DBG + +extern ULONG DebugTraceLevel; + +#ifdef _MSC_VER + +#define NDIS_DbgPrint(_t_, _x_) \ + if ((_t_ > NORMAL_MASK) \ + ? (DebugTraceLevel & _t_) > NORMAL_MASK \ + : (DebugTraceLevel & NORMAL_MASK) >= _t_) { \ + DbgPrint("(%s:%d) ", __FILE__, __LINE__); \ + DbgPrint _x_ ; \ + } + +#else /* _MSC_VER */ + +#define NDIS_DbgPrint(_t_, _x_) \ + if ((_t_ > NORMAL_MASK) \ + ? (DebugTraceLevel & _t_) > NORMAL_MASK \ + : (DebugTraceLevel & NORMAL_MASK) >= _t_) { \ + DbgPrint("(%s:%d)(%s) ", __FILE__, __LINE__, __FUNCTION__); \ + DbgPrint _x_ ; \ + } + +#endif /* _MSC_VER */ + + +#define ASSERT_IRQL(x) ASSERT(KeGetCurrentIrql() <= (x)) +#define ASSERT_IRQL_EQUAL(x) ASSERT(KeGetCurrentIrql() == (x)) + +#else /* DBG */ + +#define NDIS_DbgPrint(_t_, _x_) + +#define ASSERT_IRQL(x) +#define ASSERT_IRQL_EQUAL(x) +/* #define ASSERT(x) */ /* ndis.h */ + +#endif /* DBG */ + + +#define assert(x) ASSERT(x) +#define assert_irql(x) ASSERT_IRQL(x) + + +#ifdef _MSC_VER + +#define UNIMPLEMENTED \ + NDIS_DbgPrint(MIN_TRACE, ("The function at %s:%d is unimplemented, \ + but come back another day.\n", __FILE__, __LINE__)); + +#else /* _MSC_VER */ + +#define UNIMPLEMENTED \ + NDIS_DbgPrint(MIN_TRACE, ("%s at %s:%d is unimplemented, \ + but come back another day.\n", __FUNCTION__, __FILE__, __LINE__)); + +#endif /* _MSC_VER */ + +#define UNIMPLEMENTED_DBGBREAK(...) \ + do { \ + NDIS_DbgPrint(MIN_TRACE, ("UNIMPLEMENTED.\n")); \ + DbgPrint("" __VA_ARGS__); \ + DbgBreakPoint(); \ + } while (0) + + +#define CHECKPOINT \ + do { NDIS_DbgPrint(MIN_TRACE, ("%s:%d\n", __FILE__, __LINE__)); } while(0); + + +#define NDIS_MinDbgPrint(...) NDIS_DbgPrint(MIN_TRACE, (__VA_ARGS__)) + +/* EOF */ diff --git a/drivers/network/dd/b57xx/hardware.c b/drivers/network/dd/b57xx/hardware.c new file mode 100644 index 0000000000000..64849dca8fcf6 --- /dev/null +++ b/drivers/network/dd/b57xx/hardware.c @@ -0,0 +1,474 @@ +/* + * 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 + */ + +#include "nic.h" + +#include "debug.h" + +/* NIC FUNCTIONS **************************************************************/ + +NDIS_STATUS +NTAPI +NICInitializeAdapterResources(IN PB57XX_ADAPTER Adapter, + IN PNDIS_RESOURCE_LIST ResourceList) +{ + for (UINT n = 0; n < ResourceList->Count; n++) + { + PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor = ResourceList->PartialDescriptors + n; + + switch (ResourceDescriptor->Type) + { + case CmResourceTypePort: + ASSERT(Adapter->IoPortAddress == 0); + ASSERT(ResourceDescriptor->u.Port.Start.HighPart == 0); + + Adapter->IoPortAddress = ResourceDescriptor->u.Port.Start.LowPart; + Adapter->IoPortLength = ResourceDescriptor->u.Port.Length; + + 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); + + Adapter->InterruptVector = ResourceDescriptor->u.Interrupt.Vector; + Adapter->InterruptLevel = ResourceDescriptor->u.Interrupt.Level; + Adapter->InterruptShared = (ResourceDescriptor->ShareDisposition == + CmResourceShareShared); + Adapter->InterruptFlags = ResourceDescriptor->Flags; + + 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; + + default: + NDIS_MinDbgPrint("Unrecognized resource type: 0x%x\n", ResourceDescriptor->Type); + break; + } + } + + if (Adapter->IoAddress.QuadPart == 0 || + Adapter->IoPortAddress == 0 || + Adapter->InterruptVector == 0) + { + NDIS_MinDbgPrint("Adapter didn't receive enough resources\n"); + return NDIS_STATUS_RESOURCES; + } + + return NDIS_STATUS_SUCCESS; +} + +BOOLEAN +NTAPI +NICRecognizeHardware(IN PB57XX_ADAPTER Adapter) +{ + NDIS_MinDbgPrint("NICRecognizeHardware\n"); + + return FALSE; +} + +NDIS_STATUS +NTAPI +NICAllocateIoResources(IN PB57XX_ADAPTER Adapter) +{ + NDIS_STATUS Status; + //ULONG AllocationSize; + + NDIS_MinDbgPrint("NICAllocateIoResources\n"); + + Status = NdisMRegisterIoPortRange((PVOID*)&Adapter->IoPort, + Adapter->MiniportAdapterHandle, + Adapter->IoPortAddress, + Adapter->IoPortLength); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_MinDbgPrint("Unable to register IO port range (0x%x)\n", Status); + return NDIS_STATUS_RESOURCES; + } + + 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) + { + NDIS_MinDbgPrint("Unable to allocate transmit descriptors\n")); + return NDIS_STATUS_RESOURCES; + } + + for (UINT n = 0; n < NUM_TRANSMIT_DESCRIPTORS; ++n) + { + PEB57XXTRANSMIT_DESCRIPTOR Descriptor = Adapter->TransmitDescriptors + n; + Descriptor->Address = 0; + Descriptor->Length = 0; + } + + NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, + sizeof(EB57XXRECEIVE_DESCRIPTOR) * NUM_RECEIVE_DESCRIPTORS, + FALSE, + (PVOID*)&Adapter->ReceiveDescriptors, + &Adapter->ReceiveDescriptorsPa); + if (Adapter->ReceiveDescriptors == NULL) + { + NDIS_MinDbgPrint("Unable to allocate receive descriptors\n"); + return NDIS_STATUS_RESOURCES; + } + + 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) + { + NDIS_MinDbgPrint("Unable to allocate receive buffer\n"); + return NDIS_STATUS_RESOURCES; + } + + for (UINT n = 0; n < NUM_RECEIVE_DESCRIPTORS; ++n) + { + PEB57XXRECEIVE_DESCRIPTOR Descriptor = Adapter->ReceiveDescriptors + n; + + RtlZeroMemory(Descriptor, sizeof(*Descriptor)); + Descriptor->Address = Adapter->ReceiveBufferPa.QuadPart + n * + Adapter->ReceiveBufferEntrySize; + } + + return NDIS_STATUS_SUCCESS;*/ + + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICRegisterInterrupts(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) + { + Adapter->InterruptRegistered = TRUE; + } + + return Status; +} + +NDIS_STATUS +NTAPI +NICUnregisterInterrupts(IN PB57XX_ADAPTER Adapter) +{ + NDIS_MinDbgPrint("NICUnregisterInterrupts\n"); + + if (Adapter->InterruptRegistered) + { + NdisMDeregisterInterrupt(&Adapter->Interrupt); + Adapter->InterruptRegistered = FALSE; + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICReleaseIoResources(IN PB57XX_ADAPTER Adapter) +{ + NDIS_MinDbgPrint("NICReleaseIoResources\n"); + + /*if (Adapter->ReceiveDescriptors != NULL) + { + // 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; + } + + if (Adapter->ReceiveBuffer != NULL) + { + NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, + Adapter->ReceiveBufferEntrySize * NUM_RECEIVE_DESCRIPTORS, + FALSE, + Adapter->ReceiveBuffer, + Adapter->ReceiveBufferPa); + + Adapter->ReceiveBuffer = NULL; + Adapter->ReceiveBufferEntrySize = 0; + } + + + if (Adapter->TransmitDescriptors != NULL) + { + // 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) + { + NdisMDeregisterIoPortRange(Adapter->MiniportAdapterHandle, + Adapter->IoPortAddress, + Adapter->IoPortLength, + Adapter->IoPort); + } + + if (Adapter->IoBase) + { + NdisMUnmapIoSpace(Adapter->MiniportAdapterHandle, Adapter->IoBase, Adapter->IoLength); + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICPowerOn(IN PB57XX_ADAPTER Adapter) +{ + NDIS_MinDbgPrint("NICPowerOn\n"); + + NDIS_STATUS Status = NICSoftReset(Adapter); + if (Status != NDIS_STATUS_SUCCESS) + { + return Status; + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICSoftReset(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++) + { + 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; + }*/ + } + + NDIS_MinDbgPrint("Unable to recover device"); + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICEnableTxRx(IN PB57XX_ADAPTER Adapter) +{ + NDIS_MinDbgPrint("NICEnableTxRx\n"); + + // TODO Write and read to device registers + + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICDisableTxRx(IN PB57XX_ADAPTER Adapter) +{ + NDIS_MinDbgPrint("NICDisableTxRx\n"); + + // TODO Write and read to device registers + + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICGetPermanentMacAddress(IN PB57XX_ADAPTER Adapter, + OUT PUCHAR MacAddress) +{ + USHORT AddressWord; + + NDIS_MinDbgPrint("NICGetPermanentMacAddress\n"); + + /* Should we read from RAL/RAH first? */ + for (UINT n = 0; n < (IEEE_802_ADDR_LENGTH / 2); n++) + { + 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; + } + + 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]); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICUpdateMulticastList(IN PB57XX_ADAPTER Adapter) +{ + NDIS_MinDbgPrint("NICUpdateMulticastList\n"); + + for (UINT n = 0; n < MAXIMUM_MULTICAST_ADDRESSES; ++n) + { + /*ULONG Ral = *(ULONG*)Adapter->MulticastList[n].MacAddress; + ULONG Rah = *(USHORT*)&Adapter->MulticastList[n].MacAddress[4]; + + if (Rah || Ral) + { + Rah |= B57XX_RAH_AV; + + B57XXWriteUlong(Adapter, B57XX_REG_RAL + (8*n), Ral); + B57XXWriteUlong(Adapter, B57XX_REG_RAH + (8*n), Rah); + } + else + { + B57XXWriteUlong(Adapter, B57XX_REG_RAH + (8*n), 0); + B57XXWriteUlong(Adapter, B57XX_REG_RAL + (8*n), 0); + }*/ + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICApplyPacketFilter(IN PB57XX_ADAPTER Adapter) +{ + //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); + + return NDIS_STATUS_SUCCESS;*/ + + return NDIS_STATUS_FAILURE; +} + +VOID +NTAPI +NICUpdateLinkStatus(IN PB57XX_ADAPTER Adapter) +{ + /*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];*/ +} + +/* B57XX FUNCTIONS ************************************************************/ + +BOOLEAN +B57XXReadEeprom(IN PB57XX_ADAPTER Adapter, + IN UCHAR Address, + USHORT *Result) +{ + //ULONG Value; + + for (UINT n = 0; n < MAX_EEPROM_READ_ATTEMPTS; n++) + { + NdisStallExecution(5); + + // TODO + // B57XXReadEeprom(Adapter, ???, &Value); + + /*if (Value & B57XX_EERD_DONE) + { + break; + }*/ + } + /*if (!(Value & B57XX_EERD_DONE)) + { + NDIS_MinDbgPrint("EEPROM Read incomplete\n"); + return FALSE; + }*/ + //*Result = (USHORT)(Value >> B57XX_EERD_DATA_SHIFT); + return TRUE; +} diff --git a/drivers/network/dd/b57xx/info.c b/drivers/network/dd/b57xx/info.c new file mode 100644 index 0000000000000..869beb4a2eea7 --- /dev/null +++ b/drivers/network/dd/b57xx/info.c @@ -0,0 +1,363 @@ +/* + * 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 + */ + +#include "nic.h" + +#include "debug.h" + +static NDIS_OID SupportedOidList[] = +{ + OID_GEN_SUPPORTED_LIST, + OID_GEN_CURRENT_PACKET_FILTER, + OID_GEN_HARDWARE_STATUS, + OID_GEN_MEDIA_SUPPORTED, + OID_GEN_MEDIA_IN_USE, + OID_GEN_MAXIMUM_LOOKAHEAD, + OID_GEN_MAXIMUM_FRAME_SIZE, + OID_GEN_MAXIMUM_SEND_PACKETS, + OID_GEN_LINK_SPEED, + OID_GEN_TRANSMIT_BUFFER_SPACE, + OID_GEN_RECEIVE_BUFFER_SPACE, + OID_GEN_RECEIVE_BLOCK_SIZE, + OID_GEN_TRANSMIT_BLOCK_SIZE, + OID_GEN_VENDOR_ID, + OID_GEN_VENDOR_DESCRIPTION, + OID_GEN_VENDOR_DRIVER_VERSION, + OID_GEN_CURRENT_LOOKAHEAD, + OID_802_3_MULTICAST_LIST, + OID_GEN_DRIVER_VERSION, + OID_GEN_MAXIMUM_TOTAL_SIZE, + OID_GEN_MAC_OPTIONS, + OID_GEN_MEDIA_CONNECT_STATUS, + OID_802_3_PERMANENT_ADDRESS, + OID_802_3_CURRENT_ADDRESS, + OID_802_3_MAXIMUM_LIST_SIZE, + + /* Statistics */ + OID_GEN_XMIT_OK, + OID_GEN_RCV_OK, + OID_GEN_XMIT_ERROR, + OID_GEN_RCV_ERROR, + OID_GEN_RCV_NO_BUFFER, +}; + +NDIS_STATUS +NTAPI +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; + union _GENERIC_INFORMATION + { + USHORT UShort; + ULONG ULong; + ULONG64 ULong64; + NDIS_MEDIUM Medium; + NDIS_PNP_CAPABILITIES PmCapabilities; + } GenericInfo; + PVOID CopySource = &GenericInfo; + ULONG CopyLength = sizeof(ULONG); + + switch (Oid) + { + case OID_GEN_SUPPORTED_LIST: + CopySource = (PVOID)&SupportedOidList; + CopyLength = sizeof(SupportedOidList); + break; + + case OID_GEN_CURRENT_PACKET_FILTER: + GenericInfo.ULong = Adapter->PacketFilter; + break; + + case OID_GEN_HARDWARE_STATUS: + UNIMPLEMENTED_DBGBREAK(); + GenericInfo.ULong = (ULONG)NdisHardwareStatusReady; // FIXME + break; + + case OID_GEN_MEDIA_SUPPORTED: + case OID_GEN_MEDIA_IN_USE: + { + GenericInfo.Medium = NdisMedium802_3; + CopyLength = sizeof(NDIS_MEDIUM); + break; + } + + case OID_GEN_RECEIVE_BLOCK_SIZE: + case OID_GEN_TRANSMIT_BLOCK_SIZE: + case OID_GEN_CURRENT_LOOKAHEAD: + case OID_GEN_MAXIMUM_LOOKAHEAD: + case OID_GEN_MAXIMUM_FRAME_SIZE: + GenericInfo.ULong = MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER); + break; + + case OID_802_3_MULTICAST_LIST: + CopySource = Adapter->MulticastList; + CopyLength = Adapter->MulticastListSize * IEEE_802_ADDR_LENGTH; + break; + + case OID_802_3_MAXIMUM_LIST_SIZE: + GenericInfo.ULong = MAXIMUM_MULTICAST_ADDRESSES; + break; + + case OID_GEN_LINK_SPEED: + GenericInfo.ULong = Adapter->LinkSpeedMbps * 10000; + break; + + case OID_GEN_TRANSMIT_BUFFER_SPACE: + GenericInfo.ULong = MAXIMUM_FRAME_SIZE; + break; + + case OID_GEN_RECEIVE_BUFFER_SPACE: + GenericInfo.ULong = RECEIVE_BUFFER_SIZE; + 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); + break; + + case OID_GEN_VENDOR_DESCRIPTION: + { + static UCHAR VendorDesc[] = "ReactOS Team"; + CopySource = VendorDesc; + CopyLength = sizeof(VendorDesc); + break; + } + + case OID_GEN_VENDOR_DRIVER_VERSION: + GenericInfo.ULong = DRIVER_VERSION; + break; + + case OID_GEN_DRIVER_VERSION: + { + CopyLength = sizeof(USHORT); + GenericInfo.UShort = (NDIS_MINIPORT_MAJOR_VERSION << 8) + NDIS_MINIPORT_MINOR_VERSION; + break; + } + + case OID_GEN_MAXIMUM_TOTAL_SIZE: + GenericInfo.ULong = MAXIMUM_FRAME_SIZE; + break; + + case OID_GEN_MAXIMUM_SEND_PACKETS: + GenericInfo.ULong = 1; + break; + + case OID_GEN_MAC_OPTIONS: + GenericInfo.ULong = NDIS_MAC_OPTION_RECEIVE_SERIALIZED | + NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | + NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | + NDIS_MAC_OPTION_NO_LOOPBACK; + break; + + case OID_GEN_MEDIA_CONNECT_STATUS: + GenericInfo.ULong = Adapter->MediaState; + break; + + case OID_802_3_CURRENT_ADDRESS: + CopySource = Adapter->MulticastList[0].MacAddress; + CopyLength = IEEE_802_ADDR_LENGTH; + break; + + case OID_802_3_PERMANENT_ADDRESS: + CopySource = Adapter->PermanentMacAddress; + CopyLength = IEEE_802_ADDR_LENGTH; + 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: + { + //GenericInfo.ULong64 = NICQueryStatisticCounter(Adapter, Oid); TODO + + *BytesNeeded = sizeof(ULONG64); + if (InformationBufferLength >= sizeof(ULONG64)) + { + *BytesWritten = sizeof(ULONG64); + NdisMoveMemory(InformationBuffer, CopySource, sizeof(ULONG64)); + } + else if (InformationBufferLength >= sizeof(ULONG)) + { + *BytesWritten = sizeof(ULONG); + NdisMoveMemory(InformationBuffer, CopySource, sizeof(ULONG)); + } + else + { + *BytesWritten = 0; + return NDIS_STATUS_BUFFER_TOO_SHORT; + } + return NDIS_STATUS_SUCCESS; + } + + default: + NDIS_MinDbgPrint("Unknown OID 0x%x\n", Oid); + Status = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + if (Status == NDIS_STATUS_SUCCESS) + { + if (CopyLength > InformationBufferLength) + { + *BytesNeeded = CopyLength; + *BytesWritten = 0; + Status = NDIS_STATUS_BUFFER_TOO_SHORT; + } + else + { + NdisMoveMemory(InformationBuffer, CopySource, CopyLength); + *BytesWritten = CopyLength; + *BytesNeeded = CopyLength; + } + } + else + { + *BytesWritten = 0; + *BytesNeeded = 0; + } + + NDIS_MinDbgPrint("Query OID 0x%x: %s(0x%x) (%d, %d)\n", + Oid, + Status == NDIS_STATUS_SUCCESS ? "Completed" : "Failed", + Status, + *BytesWritten, + *BytesNeeded); + + 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) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; + ULONG GenericULong; + + switch (Oid) + { + case OID_GEN_CURRENT_PACKET_FILTER: + if (InformationBufferLength < sizeof(ULONG)) + { + *BytesRead = 0; + *BytesNeeded = sizeof(ULONG); + Status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + NdisMoveMemory(&GenericULong, InformationBuffer, sizeof(ULONG)); + + if (GenericULong & + ~(NDIS_PACKET_TYPE_DIRECTED | + NDIS_PACKET_TYPE_MULTICAST | + NDIS_PACKET_TYPE_ALL_MULTICAST | + NDIS_PACKET_TYPE_BROADCAST | + NDIS_PACKET_TYPE_PROMISCUOUS | + NDIS_PACKET_TYPE_MAC_FRAME)) + { + *BytesRead = sizeof(ULONG); + *BytesNeeded = sizeof(ULONG); + Status = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + if (Adapter->PacketFilter == GenericULong) + { + break; + } + + Adapter->PacketFilter = GenericULong; + + Status = NICApplyPacketFilter(Adapter); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_MinDbgPrint("Failed to apply new packet filter (0x%x)\n", Status); + break; + } + + break; + + case OID_GEN_CURRENT_LOOKAHEAD: + if (InformationBufferLength < sizeof(ULONG)) + { + *BytesRead = 0; + *BytesNeeded = sizeof(ULONG); + Status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + NdisMoveMemory(&GenericULong, InformationBuffer, sizeof(ULONG)); + + if (GenericULong > MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER)) + { + Status = NDIS_STATUS_INVALID_DATA; + } + + break; + + case OID_802_3_MULTICAST_LIST: + if (InformationBufferLength % IEEE_802_ADDR_LENGTH) + { + *BytesRead = 0; + *BytesNeeded = InformationBufferLength + + (InformationBufferLength % IEEE_802_ADDR_LENGTH); + Status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + if (InformationBufferLength > sizeof(Adapter->MulticastList)) + { + *BytesNeeded = sizeof(Adapter->MulticastList); + *BytesRead = 0; + Status = NDIS_STATUS_MULTICAST_FULL; + break; + } + + NdisMoveMemory(Adapter->MulticastList, InformationBuffer, InformationBufferLength); + + Adapter->MulticastListSize = InformationBufferLength / IEEE_802_ADDR_LENGTH; + + NICUpdateMulticastList(Adapter); + break; + + default: + NDIS_MinDbgPrint("Unknown OID 0x%x\n", Oid); + Status = NDIS_STATUS_NOT_SUPPORTED; + *BytesRead = 0; + *BytesNeeded = 0; + break; + } + + if (Status == NDIS_STATUS_SUCCESS) + { + *BytesRead = InformationBufferLength; + *BytesNeeded = 0; + } + + NDIS_MinDbgPrint("Set Info on OID 0x%x: %s(0x%x) (%d, %d)\n", + Oid, + Status == NDIS_STATUS_SUCCESS ? "Completed" : "Failed", + Status, + *BytesRead, + *BytesNeeded); + + return Status; +} diff --git a/drivers/network/dd/b57xx/interrupt.c b/drivers/network/dd/b57xx/interrupt.c new file mode 100644 index 0000000000000..130106ef50b72 --- /dev/null +++ b/drivers/network/dd/b57xx/interrupt.c @@ -0,0 +1,51 @@ +/* + * 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 + */ + +#include "nic.h" + +#include "debug.h" + +VOID +NTAPI +MiniportISR(OUT PBOOLEAN InterruptRecognized, + OUT PBOOLEAN QueueMiniportHandleInterrupt, + IN NDIS_HANDLE MiniportAdapterContext) +{ + //ULONG Value; + //PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; + + NDIS_MinDbgPrint("B57XX ISR\n"); + + /* Reading the interrupt acknowledges them */ + /*B57XXReadUlong(Adapter, B57XX_REG_ICR, &Value); + + Value &= Adapter->InterruptMask; + _InterlockedOr(&Adapter->InterruptPending, Value); + + if (Value) + { + *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) +{ + //ULONG InterruptPending; + //PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; + + NDIS_MinDbgPrint("B57XX HandleInterrupt\n"); +} diff --git a/drivers/network/dd/b57xx/ndis.c b/drivers/network/dd/b57xx/ndis.c new file mode 100644 index 0000000000000..d46e31f3646f9 --- /dev/null +++ b/drivers/network/dd/b57xx/ndis.c @@ -0,0 +1,258 @@ +/* + * 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 + */ +#include "nic.h" + +#include "debug.h" + +ULONG DebugTraceLevel = MIN_TRACE; + +NDIS_STATUS +NTAPI +MiniportReset(OUT PBOOLEAN AddressingReset, + IN NDIS_HANDLE MiniportAdapterContext) +{ + //PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; + + *AddressingReset = FALSE; + UNIMPLEMENTED_DBGBREAK(); + return NDIS_STATUS_FAILURE; +} + +VOID +NTAPI +MiniportHalt(IN NDIS_HANDLE MiniportAdapterContext) +{ + PB57XX_ADAPTER Adapter = (PB57XX_ADAPTER)MiniportAdapterContext; + + ASSERT(Adapter != NULL); + + /* First disable sending / receiving */ + NICDisableTxRx(Adapter); + + /* Then unregister interrupts */ + NICUnregisterInterrupts(Adapter); + + /* Finally, free other resources (Ports, IO ranges,...) */ + NICReleaseIoResources(Adapter); + + /* Destroy the adapter context */ + NdisFreeMemory(Adapter, sizeof(*Adapter), 0); +} + +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 Status; + PB57XX_ADAPTER Adapter; + UINT i; + PNDIS_RESOURCE_LIST ResourceList = NULL; + UINT ResourceListSize = 0; + + /* Make sure the medium is supported */ + for (i = 0; i < MediumArraySize; i++) + { + if (MediumArray[i] == NdisMedium802_3) + { + *SelectedMediumIndex = i; + break; + } + } + if (i == MediumArraySize) + { + NDIS_MinDbgPrint("802.3 medium was not found in the medium array\n"); + return NDIS_STATUS_UNSUPPORTED_MEDIA; + } + + /* Allocate our adapter context */ + Status = NdisAllocateMemoryWithTag((PVOID*)&Adapter, sizeof(*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)); + Adapter->MiniportAdapterHandle = MiniportAdapterHandle; + + /* Notify NDIS of some characteristics of our NIC */ + NdisMSetAttributesEx(MiniportAdapterHandle, + Adapter, + 0, + NDIS_ATTRIBUTE_BUS_MASTER, + NdisInterfacePci); + + /* Get our resources for IRQ and IO base information */ + NdisMQueryAdapterResources(&Status, + WrapperConfigurationContext, + ResourceList, + &ResourceListSize); + if (Status != NDIS_STATUS_RESOURCES) + { + NDIS_MinDbgPrint("Unexpected failure of NdisMQueryAdapterResources (0x%x)\n", Status); + Status = NDIS_STATUS_FAILURE; + goto Cleanup; + } + + Status = NdisAllocateMemoryWithTag((PVOID*)&ResourceList, ResourceListSize, B57XX_TAG); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_MinDbgPrint("Failed to allocate resource list (0x%x)\n", Status); + goto Cleanup; + } + + NdisMQueryAdapterResources(&Status, + WrapperConfigurationContext, + ResourceList, + &ResourceListSize); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_MinDbgPrint("Unexpected failure of NdisMQueryAdapterResources (0x%x)\n", Status); + goto Cleanup; + } + + ASSERT(ResourceList->Version == 1); + ASSERT(ResourceList->Revision == 1); + + /* Begin hardware initialization */ + Status = NICInitializeAdapterResources(Adapter, ResourceList); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_MinDbgPrint("Adapter didn't receive enough resources\n"); + goto Cleanup; + } + + NdisFreeMemory(ResourceList, ResourceListSize, 0); + ResourceList = NULL; + + /* Allocate the DMA resources */ + Status = NdisMInitializeScatterGatherDma(MiniportAdapterHandle, FALSE, MAXIMUM_FRAME_SIZE); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_MinDbgPrint("Unable to configure DMA\n"); + Status = NDIS_STATUS_RESOURCES; + goto Cleanup; + } + + Status = NICAllocateIoResources(Adapter); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_MinDbgPrint("Unable to allocate resources\n"); + Status = NDIS_STATUS_RESOURCES; + goto Cleanup; + } + + /* Adapter setup */ + Status = NICPowerOn(Adapter); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_MinDbgPrint("Unable to power on NIC (0x%x)\n", Status); + goto Cleanup; + } + + Status = NICSoftReset(Adapter); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_MinDbgPrint("Unable to reset the NIC (0x%x)\n", Status); + goto Cleanup; + } + + Status = NICGetPermanentMacAddress(Adapter, Adapter->PermanentMacAddress); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_MinDbgPrint("Unable to get the fixed MAC address (0x%x)\n", Status); + 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); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_MinDbgPrint("Unable to register interrupt (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); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_MinDbgPrint("Unable to enable TX and RX (0x%x)\n", Status); + goto Cleanup; + } + + return NDIS_STATUS_SUCCESS; + +Cleanup: + if (ResourceList != NULL) + { + NdisFreeMemory(ResourceList, ResourceListSize, 0); + } + + MiniportHalt(Adapter); + + return Status; +} + +NTSTATUS +NTAPI +DriverEntry(IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) +{ + NDIS_HANDLE WrapperHandle; + NDIS_MINIPORT_CHARACTERISTICS Characteristics = {0}; + NDIS_STATUS Status; + + Characteristics.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION; + Characteristics.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION; + Characteristics.CheckForHangHandler = NULL; + Characteristics.DisableInterruptHandler = NULL; + Characteristics.EnableInterruptHandler = NULL; + Characteristics.HaltHandler = MiniportHalt; + Characteristics.HandleInterruptHandler = MiniportHandleInterrupt; + Characteristics.InitializeHandler = MiniportInitialize; + Characteristics.ISRHandler = MiniportISR; + Characteristics.QueryInformationHandler = MiniportQueryInformation; + Characteristics.ReconfigureHandler = NULL; + Characteristics.ResetHandler = MiniportReset; + Characteristics.SendHandler = MiniportSend; + Characteristics.SetInformationHandler = MiniportSetInformation; + Characteristics.TransferDataHandler = NULL; + Characteristics.ReturnPacketHandler = NULL; + Characteristics.SendPacketsHandler = NULL; + Characteristics.AllocateCompleteHandler = NULL; + + NdisMInitializeWrapper(&WrapperHandle, DriverObject, RegistryPath, NULL); + if (!WrapperHandle) + { + return NDIS_STATUS_FAILURE; + } + + Status = NdisMRegisterMiniport(WrapperHandle, &Characteristics, sizeof(Characteristics)); + if (Status != NDIS_STATUS_SUCCESS) + { + NdisTerminateWrapper(WrapperHandle, 0); + return NDIS_STATUS_FAILURE; + } + + return NDIS_STATUS_SUCCESS; +} diff --git a/drivers/network/dd/b57xx/netb57xx.inf b/drivers/network/dd/b57xx/netb57xx.inf new file mode 100644 index 0000000000000..0b1a97abab880 --- /dev/null +++ b/drivers/network/dd/b57xx/netb57xx.inf @@ -0,0 +1,49 @@ +; NETB57XX.INF + +[Version] +Signature = "$Windows NT$" +;Signature = "$ReactOS$" +LayoutFile = layout.inf +Class = Net +ClassGUID = {4D36E972-E325-11CE-BFC1-08002BE10318} +Provider = %ReactOS% +DriverVer = 12/24/2021,1.00 + +[DestinationDirs] +DefaultDestDir = 12 + +[Manufacturer] +%BroadcomMfg% = BroadcomMfg + +[BroadcomMfg] +%Broadcom5752.DeviceDesc% = B57XX_Inst.ndi,PCI\VEN_14E4&DEV_1600 +; %Broadcom5752M.DeviceDesc% = B57XX_Inst.ndi,PCI\VEN_14E4&DEV_1601 + +;----------------------------- B57XX DRIVER ----------------------------- + +[B57XX_Inst.ndi.NT] +Characteristics = 0x4 ; NCF_PHYSICAL +BusType = 5 ; PCIBus +CopyFiles = B57XX_CopyFiles.NT + +[B57XX_CopyFiles.NT] +b57xx.sys + +[B57XX_Inst.ndi.NT.Services] +AddService = b57xx, 0x00000002, B57XX_Service_Inst + +[B57XX_Service_Inst] +ServiceType = 1 +StartType = 3 +ErrorControl = 0 +ServiceBinary = %12%\b57xx.sys +LoadOrderGroup = NDIS + +;-------------------------------- STRINGS ------------------------------- + +[Strings] +ReactOS = "ReactOS Team" + +BroadcomMfg = "Broadcom" + +Broadcom5752.DeviceDesc = "Broadcom NetXtreme 5752 Gigabit Controller" diff --git a/drivers/network/dd/b57xx/nic.h b/drivers/network/dd/b57xx/nic.h new file mode 100644 index 0000000000000..bf6badba5e94d --- /dev/null +++ b/drivers/network/dd/b57xx/nic.h @@ -0,0 +1,234 @@ +/* + * 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 + */ +#pragma once + +#include + +#include "b57xxhw.h" + +#define B57XX_TAG '075b' + +#define MAXIMUM_FRAME_SIZE 1522 +#define RECEIVE_BUFFER_SIZE 2048 + +#define DRIVER_VERSION 1 + +#define DEFAULT_INTERRUPT_MASK 0 + +typedef struct _B57XX_ADAPTER +{ + /* NIC Memory */ + NDIS_HANDLE MiniportAdapterHandle; + 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]; + ULONG MulticastListSize; + + ULONG LinkSpeedMbps; + ULONG MediaState; + 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; +} B57XX_ADAPTER, *PB57XX_ADAPTER; + + +/* MINIPORT FUNCTIONS *********************************************************/ + +VOID +NTAPI +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); + +NDIS_STATUS +NTAPI +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); + +NDIS_STATUS +NTAPI +MiniportSetInformation(IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesRead, + OUT PULONG BytesNeeded); + + +VOID +NTAPI +MiniportISR(OUT PBOOLEAN InterruptRecognized, + OUT PBOOLEAN QueueMiniportHandleInterrupt, + IN NDIS_HANDLE MiniportAdapterContext); +VOID +NTAPI +MiniportHandleInterrupt(IN NDIS_HANDLE MiniportAdapterContext); + +NDIS_STATUS +NTAPI +MiniportSend(IN NDIS_HANDLE MiniportAdapterContext, + IN PNDIS_PACKET Packet, + IN UINT Flags); + + +/* NIC FUNCTIONS **************************************************************/ + +BOOLEAN +NTAPI +NICRecognizeHardware(IN PB57XX_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICInitializeAdapterResources(IN PB57XX_ADAPTER Adapter, + IN PNDIS_RESOURCE_LIST ResourceList); + +NDIS_STATUS +NTAPI +NICAllocateIoResources(IN PB57XX_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICRegisterInterrupts(IN PB57XX_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICUnregisterInterrupts(IN PB57XX_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICReleaseIoResources(IN PB57XX_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICPowerOn(IN PB57XX_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICSoftReset(IN PB57XX_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICEnableTxRx(IN PB57XX_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICDisableTxRx(IN PB57XX_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICGetPermanentMacAddress(IN PB57XX_ADAPTER Adapter, + OUT PUCHAR MacAddress); + +NDIS_STATUS +NTAPI +NICUpdateMulticastList(IN PB57XX_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICApplyPacketFilter(IN PB57XX_ADAPTER Adapter); + +VOID +NTAPI +NICUpdateLinkStatus(IN PB57XX_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICTransmitPacket(IN PB57XX_ADAPTER Adapter, + IN PHYSICAL_ADDRESS PhysicalAddress, + IN ULONG Length); + +/* B57XX FUNCTIONS ************************************************************/ + +BOOLEAN +B57XXReadEeprom(IN PB57XX_ADAPTER Adapter, + IN UCHAR Address, + USHORT *Result); + +FORCEINLINE +VOID +B57XXReadUlong(IN PB57XX_ADAPTER Adapter, + IN ULONG Address, + OUT PULONG Value) +{ + NdisReadRegisterUlong((PULONG)(Adapter->IoBase + Address), Value); +} + +FORCEINLINE +VOID +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) +{ + //volatile ULONG Dummy; + + NdisRawWritePortUlong((PULONG)(Adapter->IoPort), Address); + //NdisReadRegisterUlong(Adapter->IoBase + B57XX_REG_STATUS, &Dummy); TODO + NdisRawWritePortUlong((PULONG)(Adapter->IoPort + 4), Value); +} + +FORCEINLINE +VOID +NICApplyInterruptMask(IN PB57XX_ADAPTER Adapter) +{ + //B57XXWriteUlong(Adapter, B57XX_REG_IMS, Adapter->InterruptMask); +} + +FORCEINLINE +VOID +NICDisableInterrupts(IN PB57XX_ADAPTER Adapter) +{ + //B57XXWriteUlong(Adapter, B57XX_REG_IMC, ~0); +} \ No newline at end of file diff --git a/drivers/network/dd/b57xx/send.c b/drivers/network/dd/b57xx/send.c new file mode 100644 index 0000000000000..6c084700298a1 --- /dev/null +++ b/drivers/network/dd/b57xx/send.c @@ -0,0 +1,63 @@ +/* + * 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; +}