Author: cgutman Date: Fri Jul 5 04:18:32 2013 New Revision: 59427
URL: http://svn.reactos.org/svn/reactos?rev=59427&view=rev Log: [RTL8139] - Add an RTL8139 driver based on documentation on OSDev, our existing drivers, and some prior work by Z98 - It should fully work on emulated and real RTL8139 hardware (I developed against QEMU's RTL8139) - It's not 100% complete (some reset and halt paths aren't done) but everything I tested worked (ping, dwnl, rapps, Firefox)
Added: trunk/reactos/drivers/network/dd/rtl8139/CMakeLists.txt (with props) trunk/reactos/drivers/network/dd/rtl8139/debug.h (with props) trunk/reactos/drivers/network/dd/rtl8139/hardware.c (with props) trunk/reactos/drivers/network/dd/rtl8139/info.c (with props) trunk/reactos/drivers/network/dd/rtl8139/interrupt.c (with props) trunk/reactos/drivers/network/dd/rtl8139/ndis.c (with props) trunk/reactos/drivers/network/dd/rtl8139/nic.h (with props) trunk/reactos/drivers/network/dd/rtl8139/rtl8139.rc (with props) trunk/reactos/drivers/network/dd/rtl8139/rtlhw.h (with props) trunk/reactos/media/inf/netrtl.inf (with props) Removed: trunk/reactos/drivers/network/dd/rtl8139/include/ Modified: trunk/reactos/drivers/network/dd/CMakeLists.txt trunk/reactos/media/inf/CMakeLists.txt
Modified: trunk/reactos/drivers/network/dd/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/dd/CMakeLis... ============================================================================== --- trunk/reactos/drivers/network/dd/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/drivers/network/dd/CMakeLists.txt [iso-8859-1] Fri Jul 5 04:18:32 2013 @@ -1,3 +1,4 @@
add_subdirectory(ne2000) add_subdirectory(pcnet) +add_subdirectory(rtl8139)
Added: trunk/reactos/drivers/network/dd/rtl8139/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/dd/rtl8139/... ============================================================================== --- trunk/reactos/drivers/network/dd/rtl8139/CMakeLists.txt (added) +++ trunk/reactos/drivers/network/dd/rtl8139/CMakeLists.txt [iso-8859-1] Fri Jul 5 04:18:32 2013 @@ -0,0 +1,18 @@ + +add_definitions( + -DNDIS50_MINIPORT + -DNDIS_MINIPORT_DRIVER + -DNDIS_LEGACY_MINIPORT) + +list(APPEND SOURCE + ndis.c + hardware.c + info.c + interrupt.c + rtl8139.rc) + +add_library(rtl8139 SHARED ${SOURCE}) +add_pch(rtl8139 pcnet.h) +set_module_type(rtl8139 kernelmodedriver) +add_importlibs(rtl8139 ndis ntoskrnl hal) +add_cd_file(TARGET rtl8139 DESTINATION reactos/system32/drivers FOR all)
Propchange: trunk/reactos/drivers/network/dd/rtl8139/CMakeLists.txt ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/network/dd/rtl8139/debug.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/dd/rtl8139/... ============================================================================== --- trunk/reactos/drivers/network/dd/rtl8139/debug.h (added) +++ trunk/reactos/drivers/network/dd/rtl8139/debug.h [iso-8859-1] Fri Jul 5 04:18:32 2013 @@ -0,0 +1,82 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Novell Eagle 2000 driver + * FILE: include/debug.h + * 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 (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \ + ((DebugTraceLevel & _t_) > NORMAL_MASK)) { \ + DbgPrint("(%s:%d) ", __FILE__, __LINE__); \ + DbgPrint _x_ ; \ + } + +#else /* _MSC_VER */ + +#define NDIS_DbgPrint(_t_, _x_) \ + if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \ + ((DebugTraceLevel & _t_) > NORMAL_MASK)) { \ + 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 CHECKPOINT \ + do { NDIS_DbgPrint(MIN_TRACE, ("%s:%d\n", __FILE__, __LINE__)); } while(0); + +/* EOF */
Propchange: trunk/reactos/drivers/network/dd/rtl8139/debug.h ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/network/dd/rtl8139/hardware.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/dd/rtl8139/... ============================================================================== --- trunk/reactos/drivers/network/dd/rtl8139/hardware.c (added) +++ trunk/reactos/drivers/network/dd/rtl8139/hardware.c [iso-8859-1] Fri Jul 5 04:18:32 2013 @@ -0,0 +1,235 @@ +/* + * ReactOS Realtek 8139 Driver + * + * Copyright (C) 2013 Cameron Gutman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "nic.h" + +#define NDEBUG +#include <debug.h> + +NDIS_STATUS +NTAPI +NICPowerOn ( + IN PRTL_ADAPTER Adapter + ) +{ + // + // Send 0x00 to the CONFIG_1 register (0x52) to set the LWAKE + LWPTN to active high. + // This should essentially *power on* the device. + // -- OSDev Wiki + // + NdisRawWritePortUchar(Adapter->IoBase + R_CFG1, 0x00); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICSoftReset ( + IN PRTL_ADAPTER Adapter + ) +{ + UCHAR commandReg; + UINT resetAttempts; + + // + // Sending 0x10 to the Command register (0x37) will send the RTL8139 into a software reset. + // Once that byte is sent, the RST bit must be checked to make sure that the chip has finished the reset. + // If the RST bit is high (1), then the reset is still in operation. + // -- OSDev Wiki + NdisRawWritePortUchar(Adapter->IoBase + R_CMD, B_CMD_RST); + + for (resetAttempts = 0; resetAttempts < MAX_RESET_ATTEMPTS; resetAttempts++) + { + NdisRawReadPortUchar(Adapter->IoBase + R_CMD, &commandReg); + + if (!(commandReg & B_CMD_RST)) + { + return NDIS_STATUS_SUCCESS; + } + + NdisMSleep(100); + } + + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICRegisterReceiveBuffer ( + IN PRTL_ADAPTER Adapter + ) +{ + ASSERT(NdisGetPhysicalAddressHigh(Adapter->ReceiveBufferPa) == 0); + + NdisRawWritePortUlong(Adapter->IoBase + R_RXSA, Adapter->ReceiveBufferPa.LowPart); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICRemoveReceiveBuffer ( + IN PRTL_ADAPTER Adapter + ) +{ + NdisRawWritePortUlong(Adapter->IoBase + R_RXSA, 0); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICEnableTxRx ( + IN PRTL_ADAPTER Adapter + ) +{ + NdisRawWritePortUchar(Adapter->IoBase + R_CMD, B_CMD_TXE | B_CMD_RXE); + + // + // TX and RX must be enabled before setting these + // + NdisRawWritePortUlong(Adapter->IoBase + R_RC, RC_VAL); + NdisRawWritePortUlong(Adapter->IoBase + R_TC, TC_VAL); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICGetPermanentMacAddress ( + IN PRTL_ADAPTER Adapter, + OUT PUCHAR MacAddress + ) +{ + UINT i; + + for (i = 0; i < IEEE_802_ADDR_LENGTH; i++) + { + NdisRawReadPortUchar(Adapter->IoBase + R_MAC + i, &MacAddress[i]); + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICApplyInterruptMask ( + IN PRTL_ADAPTER Adapter + ) +{ + NdisRawWritePortUshort(Adapter->IoBase + R_IM, Adapter->InterruptMask); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICDisableInterrupts ( + IN PRTL_ADAPTER Adapter + ) +{ + NdisRawWritePortUshort(Adapter->IoBase + R_IM, 0); + return NDIS_STATUS_SUCCESS; +} + +USHORT +NTAPI +NICInterruptRecognized ( + IN PRTL_ADAPTER Adapter, + OUT PBOOLEAN InterruptRecognized + ) +{ + USHORT interruptStatus; + + NdisRawReadPortUshort(Adapter->IoBase + R_IS, &interruptStatus); + + *InterruptRecognized = (interruptStatus & Adapter->InterruptMask) != 0; + + return (interruptStatus & Adapter->InterruptMask); +} + +VOID +NTAPI +NICAcknowledgeInterrupts ( + IN PRTL_ADAPTER Adapter + ) +{ + NdisRawWritePortUshort(Adapter->IoBase + R_IS, Adapter->InterruptPending); +} + +VOID +NTAPI +NICUpdateLinkStatus ( + IN PRTL_ADAPTER Adapter + ) +{ + UCHAR mediaState; + + NdisRawReadPortUchar(Adapter->IoBase + R_MS, &mediaState); + Adapter->MediaState = (mediaState & R_MS_LINKDWN) ? NdisMediaStateDisconnected : + NdisMediaStateConnected; + Adapter->LinkSpeedMbps = (mediaState & R_MS_SPEED_10) ? 10 : 100; +} + +NDIS_STATUS +NTAPI +NICApplyPacketFilter ( + IN PRTL_ADAPTER Adapter + ) +{ + ULONG filterMask; + + filterMask = RC_VAL; + + if (Adapter->PacketFilter & NDIS_PACKET_TYPE_DIRECTED) + { + filterMask |= B_RC_APM; + } + + if (Adapter->PacketFilter & NDIS_PACKET_TYPE_MULTICAST) + { + filterMask |= B_RC_AM; + } + + if (Adapter->PacketFilter & NDIS_PACKET_TYPE_BROADCAST) + { + filterMask |= B_RC_AB; + } + + if (Adapter->PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) + { + filterMask |= B_RC_AAP; + } + + NdisRawWritePortUlong(Adapter->IoBase + R_RC, filterMask); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICTransmitPacket ( + IN PRTL_ADAPTER Adapter, + IN UCHAR TxDesc, + IN ULONG PhysicalAddress, + IN ULONG Length + ) +{ + NdisRawWritePortUlong(Adapter->IoBase + R_TXSAD0 + (TxDesc * sizeof(ULONG)), PhysicalAddress); + NdisRawWritePortUlong(Adapter->IoBase + R_TXSTS0 + (TxDesc * sizeof(ULONG)), Length); + return NDIS_STATUS_SUCCESS; +}
Propchange: trunk/reactos/drivers/network/dd/rtl8139/hardware.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/network/dd/rtl8139/info.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/dd/rtl8139/... ============================================================================== --- trunk/reactos/drivers/network/dd/rtl8139/info.c (added) +++ trunk/reactos/drivers/network/dd/rtl8139/info.c [iso-8859-1] Fri Jul 5 04:18:32 2013 @@ -0,0 +1,394 @@ +/* + * ReactOS Realtek 8139 Driver + * + * Copyright (C) 2013 Cameron Gutman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "nic.h" + +#define NDEBUG +#include <debug.h> + +static ULONG SupportedOidList[] = +{ + OID_GEN_SUPPORTED_LIST, + OID_GEN_HARDWARE_STATUS, + OID_GEN_MEDIA_SUPPORTED, + OID_GEN_MEDIA_IN_USE, + OID_GEN_MAXIMUM_LOOKAHEAD, + OID_GEN_MAXIMUM_FRAME_SIZE, + 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_PACKET_FILTER, + OID_GEN_CURRENT_LOOKAHEAD, + OID_GEN_DRIVER_VERSION, + OID_GEN_MAXIMUM_TOTAL_SIZE, + OID_GEN_PROTOCOL_OPTIONS, + OID_GEN_MAC_OPTIONS, + OID_GEN_MEDIA_CONNECT_STATUS, + OID_GEN_MAXIMUM_SEND_PACKETS, + OID_GEN_XMIT_OK, + OID_GEN_RCV_OK, + OID_GEN_XMIT_ERROR, + OID_GEN_RCV_ERROR, + OID_GEN_RCV_NO_BUFFER, + OID_GEN_RCV_CRC_ERROR, + OID_802_3_PERMANENT_ADDRESS, + OID_802_3_CURRENT_ADDRESS, + OID_802_3_MULTICAST_LIST, + OID_802_3_MAXIMUM_LIST_SIZE, + OID_802_3_MAC_OPTIONS, + OID_802_3_RCV_ERROR_ALIGNMENT, + OID_802_3_XMIT_ONE_COLLISION, + OID_802_3_XMIT_MORE_COLLISIONS +}; + +NDIS_STATUS +NTAPI +MiniportQueryInformation ( + IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesWritten, + OUT PULONG BytesNeeded + ) +{ + PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext; + ULONG genericUlong; + ULONG copyLength; + PVOID copySource; + NDIS_STATUS status; + + status = NDIS_STATUS_SUCCESS; + copySource = &genericUlong; + copyLength = sizeof(ULONG); + + NdisAcquireSpinLock(&adapter->Lock); + + switch (Oid) + { + case OID_GEN_SUPPORTED_LIST: + copySource = (PVOID)&SupportedOidList; + copyLength = sizeof(SupportedOidList); + break; + + case OID_GEN_CURRENT_PACKET_FILTER: + genericUlong = adapter->PacketFilter; + break; + + case OID_GEN_HARDWARE_STATUS: + genericUlong = (ULONG)NdisHardwareStatusReady; //FIXME + break; + + case OID_GEN_MEDIA_SUPPORTED: + case OID_GEN_MEDIA_IN_USE: + { + static const NDIS_MEDIUM medium = NdisMedium802_3; + copySource = (PVOID)&medium; + copyLength = sizeof(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: + genericUlong = MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER); + break; + + case OID_GEN_LINK_SPEED: + genericUlong = adapter->LinkSpeedMbps * 1000; + break; + + case OID_GEN_TRANSMIT_BUFFER_SPACE: + genericUlong = MAXIMUM_FRAME_SIZE; + break; + + case OID_GEN_RECEIVE_BUFFER_SPACE: + genericUlong = RECEIVE_BUFFER_SIZE; + break; + + case OID_GEN_VENDOR_ID: + // + // The 3 bytes of the MAC address is the vendor ID + // + genericUlong = 0; + genericUlong |= (adapter->PermanentMacAddress[0] << 16); + genericUlong |= (adapter->PermanentMacAddress[1] << 8); + genericUlong |= (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: + genericUlong = DRIVER_VERSION; + break; + + case OID_GEN_DRIVER_VERSION: + { + static const USHORT driverVersion = + (NDIS_MINIPORT_MAJOR_VERSION << 8) + NDIS_MINIPORT_MINOR_VERSION; + copySource = (PVOID)&driverVersion; + copyLength = sizeof(driverVersion); + break; + } + + case OID_GEN_MAXIMUM_TOTAL_SIZE: + genericUlong = MAXIMUM_FRAME_SIZE; + break; + + case OID_GEN_PROTOCOL_OPTIONS: + NDIS_DbgPrint(MIN_TRACE, ("OID_GEN_PROTOCOL_OPTIONS is unimplemented\n")); + status = NDIS_STATUS_NOT_SUPPORTED; + break; + + case OID_GEN_MAC_OPTIONS: + genericUlong = 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: + genericUlong = adapter->MediaState; + break; + + case OID_GEN_MAXIMUM_SEND_PACKETS: + genericUlong = 1; + break; + + case OID_802_3_CURRENT_ADDRESS: + copySource = adapter->CurrentMacAddress; + copyLength = IEEE_802_ADDR_LENGTH; + break; + + case OID_802_3_PERMANENT_ADDRESS: + copySource = adapter->PermanentMacAddress; + copyLength = IEEE_802_ADDR_LENGTH; + break; + + case OID_802_3_MAXIMUM_LIST_SIZE: + genericUlong = MAXIMUM_MULTICAST_ADDRESSES; + break; + + case OID_GEN_XMIT_OK: + genericUlong = adapter->TransmitOk; + break; + + case OID_GEN_RCV_OK: + genericUlong = adapter->ReceiveOk; + break; + + case OID_GEN_XMIT_ERROR: + genericUlong = adapter->TransmitError; + break; + + case OID_GEN_RCV_ERROR: + genericUlong = adapter->ReceiveError; + break; + + case OID_GEN_RCV_NO_BUFFER: + genericUlong = adapter->ReceiveNoBufferSpace; + break; + + case OID_GEN_RCV_CRC_ERROR: + genericUlong = adapter->ReceiveCrcError; + break; + + case OID_802_3_RCV_ERROR_ALIGNMENT: + genericUlong = adapter->ReceiveAlignmentError; + break; + + case OID_802_3_XMIT_ONE_COLLISION: + genericUlong = adapter->TransmitOneCollision; + break; + + case OID_802_3_XMIT_MORE_COLLISIONS: + genericUlong = adapter->TransmitMoreCollisions; + break; + + default: + NDIS_DbgPrint(MIN_TRACE, ("Unknown OID\n")); + status = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + if (status == NDIS_STATUS_SUCCESS) + { + if (copyLength > InformationBufferLength) + { + *BytesNeeded = copyLength; + *BytesWritten = 0; + status = NDIS_STATUS_INVALID_LENGTH; + } + else + { + NdisMoveMemory(InformationBuffer, copySource, copyLength); + *BytesWritten = copyLength; + *BytesNeeded = copyLength; + } + } + else + { + *BytesWritten = 0; + *BytesNeeded = 0; + } + + NdisReleaseSpinLock(&adapter->Lock); + + NDIS_DbgPrint(MAX_TRACE, ("Query OID 0x%x: Completed with status 0x%x (%d, %d)\n", + Oid, 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 + ) +{ + PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext; + ULONG genericUlong; + NDIS_STATUS status; + + status = NDIS_STATUS_SUCCESS; + + NdisAcquireSpinLock(&adapter->Lock); + + 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_ALL_FUNCTIONAL | + NDIS_PACKET_TYPE_FUNCTIONAL | + NDIS_PACKET_TYPE_GROUP | + NDIS_PACKET_TYPE_MAC_FRAME | + NDIS_PACKET_TYPE_SMT | + NDIS_PACKET_TYPE_SOURCE_ROUTING)) + { + *BytesRead = sizeof(ULONG); + *BytesNeeded = sizeof(ULONG); + status = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + adapter->PacketFilter = genericUlong; + + status = NICApplyPacketFilter(adapter); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Failed to apply new packet filter\n")); + 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; + } + else + { + // Ignore this... + } + + 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 / 6 > MAXIMUM_MULTICAST_ADDRESSES) + { + *BytesNeeded = MAXIMUM_MULTICAST_ADDRESSES * IEEE_802_ADDR_LENGTH; + *BytesRead = 0; + status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + NdisMoveMemory(adapter->MulticastList, InformationBuffer, InformationBufferLength); + + // FIXME: Write to device + + break; + + default: + NDIS_DbgPrint(MIN_TRACE, ("Unknown OID\n")); + status = NDIS_STATUS_NOT_SUPPORTED; + *BytesRead = 0; + *BytesNeeded = 0; + break; + } + + if (status == NDIS_STATUS_SUCCESS) + { + *BytesRead = InformationBufferLength; + *BytesNeeded = 0; + } + + NdisReleaseSpinLock(&adapter->Lock); + + return status; +} +
Propchange: trunk/reactos/drivers/network/dd/rtl8139/info.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/network/dd/rtl8139/interrupt.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/dd/rtl8139/... ============================================================================== --- trunk/reactos/drivers/network/dd/rtl8139/interrupt.c (added) +++ trunk/reactos/drivers/network/dd/rtl8139/interrupt.c [iso-8859-1] Fri Jul 5 04:18:32 2013 @@ -0,0 +1,210 @@ +/* + * ReactOS Realtek 8139 Driver + * + * Copyright (C) 2013 Cameron Gutman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "nic.h" + +#define NDEBUG +#include <debug.h> + +VOID +NTAPI +MiniportISR ( + OUT PBOOLEAN InterruptRecognized, + OUT PBOOLEAN QueueMiniportHandleInterrupt, + IN NDIS_HANDLE MiniportAdapterContext + ) +{ + PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext; + ULONG csConfig; + + // + // FIXME: We need to synchronize with this ISR for changes to InterruptPending, + // LinkChange, MediaState, and LinkSpeedMbps. We can get away with IRQL + // synchronization on non-SMP machines because we run a DIRQL here. + // + + adapter->InterruptPending |= NICInterruptRecognized(adapter, InterruptRecognized); + if (!(*InterruptRecognized)) + { + // + // This is not ours. + // + *QueueMiniportHandleInterrupt = FALSE; + return; + } + + // + // We have to check for a special link change interrupt before acknowledging + // + if (adapter->InterruptPending & R_I_RXUNDRUN) + { + NdisRawReadPortUlong(adapter->IoBase + R_CSCFG, &csConfig); + if (csConfig & R_CSCR_LINKCHNG) + { + adapter->LinkChange = TRUE; + NICUpdateLinkStatus(adapter); + } + } + + // + // Acknowledge the interrupt and mark the events pending service + // + NICAcknowledgeInterrupts(adapter); + *QueueMiniportHandleInterrupt = TRUE; +} + +VOID +NTAPI +MiniportHandleInterrupt ( + IN NDIS_HANDLE MiniportAdapterContext + ) +{ + PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext; + ULONG i; + ULONG txStatus; + UCHAR command; + PPACKET_HEADER nicHeader; + PETH_HEADER ethHeader; + + NdisDprAcquireSpinLock(&adapter->Lock); + + NDIS_DbgPrint(MAX_TRACE, ("Interrupts pending: 0x%x\n", adapter->InterruptPending)); + + // + // Handle a link change + // + if (adapter->LinkChange) + { + NdisDprReleaseSpinLock(&adapter->Lock); + NdisMIndicateStatus(adapter->MiniportAdapterHandle, + adapter->MediaState == NdisMediaStateConnected ? + NDIS_STATUS_MEDIA_CONNECT : NDIS_STATUS_MEDIA_DISCONNECT, + NULL, + 0); + NdisMIndicateStatusComplete(adapter->MiniportAdapterHandle); + NdisDprAcquireSpinLock(&adapter->Lock); + adapter->LinkChange = FALSE; + } + + // + // Handle a TX interrupt + // + if (adapter->InterruptPending & (R_I_TXOK | R_I_TXERR)) + { + while (adapter->TxFull || adapter->DirtyTxDesc != adapter->CurrentTxDesc) + { + NdisRawReadPortUlong(adapter->IoBase + R_TXSTS0 + + (adapter->DirtyTxDesc * sizeof(ULONG)), &txStatus); + + if (!(txStatus & (R_TXS_STATOK | R_TXS_UNDERRUN | R_TXS_ABORTED))) + { + // + // Not sent yet + // + break; + } + + NDIS_DbgPrint(MAX_TRACE, ("Transmission for desc %d complete: 0x%x\n", + adapter->DirtyTxDesc, txStatus)); + + if (txStatus & R_TXS_STATOK) + { + adapter->TransmitOk++; + } + else + { + adapter->TransmitError++; + } + + adapter->DirtyTxDesc++; + adapter->DirtyTxDesc %= TX_DESC_COUNT; + adapter->InterruptPending &= ~(R_I_TXOK | R_I_TXERR); + adapter->TxFull = FALSE; + } + } + + // + // Handle a good RX interrupt + // + if (adapter->InterruptPending & (R_I_RXOK | R_I_RXERR)) + { + for (i = 0; i < MAX_RECEIVES_PER_INT; i++) + { + NdisRawReadPortUchar(adapter->IoBase + R_CMD, &command); + if (command & R_CMD_RXEMPTY) + { + // + // The buffer is empty + // + adapter->InterruptPending &= ~(R_I_RXOK | R_I_RXERR); + break; + } + + adapter->ReceiveOffset %= RECEIVE_BUFFER_SIZE; + + NDIS_DbgPrint(MAX_TRACE, ("Looking for a packet at offset 0x%x\n", + adapter->ReceiveOffset)); + nicHeader = (PPACKET_HEADER)(adapter->ReceiveBuffer + adapter->ReceiveOffset); + if (!(nicHeader->Status & RSR_ROK)) + { + // + // Receive failed + // + NDIS_DbgPrint(MIN_TRACE, ("Receive failed: 0x%x\n", nicHeader->Status)); + + if (nicHeader->Status & RSR_FAE) + { + adapter->ReceiveAlignmentError++; + } + else if (nicHeader->Status & RSR_CRC) + { + adapter->ReceiveCrcError++; + } + adapter->ReceiveError++; + + goto NextPacket; + } + + NDIS_DbgPrint(MAX_TRACE, ("Indicating %d byte packet to NDIS\n", + nicHeader->PacketLength - RECV_CRC_LENGTH)); + + ethHeader = (PETH_HEADER)(nicHeader + 1); + NdisMEthIndicateReceive(adapter->MiniportAdapterHandle, + NULL, + (PVOID)(ethHeader), + sizeof(ETH_HEADER), + (PVOID)(ethHeader + 1), + nicHeader->PacketLength - sizeof(ETH_HEADER) - RECV_CRC_LENGTH, + nicHeader->PacketLength - sizeof(ETH_HEADER) - RECV_CRC_LENGTH); + adapter->ReceiveOk++; + + NextPacket: + adapter->ReceiveOffset += nicHeader->PacketLength + sizeof(PACKET_HEADER); + adapter->ReceiveOffset = (adapter->ReceiveOffset + 3) & ~3; + NdisRawWritePortUshort(adapter->IoBase + R_CAPR, adapter->ReceiveOffset - 0x10); + } + + NdisMEthIndicateReceiveComplete(adapter->MiniportAdapterHandle); + } + + NdisDprReleaseSpinLock(&adapter->Lock); +} +
Propchange: trunk/reactos/drivers/network/dd/rtl8139/interrupt.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/network/dd/rtl8139/ndis.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/dd/rtl8139/... ============================================================================== --- trunk/reactos/drivers/network/dd/rtl8139/ndis.c (added) +++ trunk/reactos/drivers/network/dd/rtl8139/ndis.c [iso-8859-1] Fri Jul 5 04:18:32 2013 @@ -0,0 +1,525 @@ +/* + * ReactOS Realtek 8139 Driver + * + * Copyright (C) 2013 Cameron Gutman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "nic.h" + +#define NDEBUG +#include <debug.h> + +ULONG DebugTraceLevel = MIN_TRACE; + +NDIS_STATUS +NTAPI +MiniportReset ( + OUT PBOOLEAN AddressingReset, + IN NDIS_HANDLE MiniportAdapterContext + ) +{ + *AddressingReset = FALSE; + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +MiniportSend ( + IN NDIS_HANDLE MiniportAdapterContext, + IN PNDIS_PACKET Packet, + IN UINT Flags + ) +{ + PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext; + NDIS_STATUS status; + PSCATTER_GATHER_LIST sgList = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, + ScatterGatherListPacketInfo); + ULONG transmitLength; + ULONG transmitBuffer; + PNDIS_BUFFER firstBuffer; + PVOID firstBufferVa; + UINT firstBufferLength, totalBufferLength; + PUCHAR runtBuffer; + + ASSERT(sgList != NULL); + + ASSERT(sgList->NumberOfElements == 1); + ASSERT(sgList->Elements[0].Address.HighPart == 0); + ASSERT((sgList->Elements[0].Address.LowPart & 3) == 0); + ASSERT(sgList->Elements[0].Length <= MAXIMUM_FRAME_SIZE); + + NDIS_DbgPrint(MAX_TRACE, ("Sending %d byte packet\n", sgList->Elements[0].Length)); + + NdisAcquireSpinLock(&adapter->Lock); + + if (adapter->TxFull) + { + NDIS_DbgPrint(MIN_TRACE, ("All TX descriptors are full\n")); + NdisReleaseSpinLock(&adapter->Lock); + return NDIS_STATUS_RESOURCES; + } + + NDIS_DbgPrint(MAX_TRACE, ("Sending packet on TX desc %d\n", adapter->CurrentTxDesc)); + + // + // If this is a runt, we need to pad it manually for the RTL8139 + // + if (sgList->Elements[0].Length < MINIMUM_FRAME_SIZE) + { + transmitLength = MINIMUM_FRAME_SIZE; + transmitBuffer = adapter->RuntTxBuffersPa.LowPart + + (MINIMUM_FRAME_SIZE * adapter->CurrentTxDesc); + + NdisGetFirstBufferFromPacketSafe(Packet, + &firstBuffer, + &firstBufferVa, + &firstBufferLength, + &totalBufferLength, + NormalPagePriority); + if (firstBufferVa == NULL) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to get buffer from packet\n")); + NdisReleaseSpinLock(&adapter->Lock); + return NDIS_STATUS_RESOURCES; + } + + ASSERT(firstBufferLength == totalBufferLength); + + runtBuffer = adapter->RuntTxBuffers + (MINIMUM_FRAME_SIZE * adapter->CurrentTxDesc); + RtlCopyMemory(runtBuffer, firstBufferVa, firstBufferLength); + RtlFillMemory(runtBuffer + firstBufferLength, MINIMUM_FRAME_SIZE - firstBufferLength, 0x00); + } + else + { + transmitLength = sgList->Elements[0].Length; + transmitBuffer = sgList->Elements[0].Address.LowPart; + } + + status = NICTransmitPacket(adapter, adapter->CurrentTxDesc, transmitBuffer, transmitLength); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Transmit packet failed\n")); + NdisReleaseSpinLock(&adapter->Lock); + return status; + } + + adapter->CurrentTxDesc++; + adapter->CurrentTxDesc %= TX_DESC_COUNT; + + if (adapter->CurrentTxDesc == adapter->DirtyTxDesc) + { + NDIS_DbgPrint(MID_TRACE, ("All TX descriptors are full now\n")); + adapter->TxFull = TRUE; + } + + NdisReleaseSpinLock(&adapter->Lock); + + return NDIS_STATUS_SUCCESS; +} + +VOID +NTAPI +MiniportHalt ( + IN NDIS_HANDLE MiniportAdapterContext + ) +{ + PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext; + + ASSERT(adapter != NULL); + + // + // Interrupts need to stop first + // + if (adapter->InterruptRegistered != FALSE) + { + NdisMDeregisterInterrupt(&adapter->Interrupt); + } + + // + // If we have a mapped IO port range, we can talk to the NIC + // + if (adapter->IoBase != NULL) + { + if (adapter->ReceiveBuffer != NULL) + { + // + // Disassociate our shared buffer before freeing it to avoid + // NIC-induced memory corruption + // + NICRemoveReceiveBuffer(adapter); + + NdisMFreeSharedMemory(adapter->MiniportAdapterHandle, + adapter->ReceiveBufferLength, + FALSE, + adapter->ReceiveBuffer, + adapter->ReceiveBufferPa); + } + + if (adapter->RuntTxBuffers != NULL) + { + NdisMFreeSharedMemory(adapter->MiniportAdapterHandle, + MINIMUM_FRAME_SIZE * TX_DESC_COUNT, + FALSE, + adapter->RuntTxBuffers, + adapter->RuntTxBuffersPa); + } + + // + // Unregister the IO range + // + NdisMDeregisterIoPortRange(adapter->MiniportAdapterHandle, + adapter->IoRangeStart, + adapter->IoRangeLength, + adapter->IoBase); + } + + // + // 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 + ) +{ + PRTL_ADAPTER adapter; + NDIS_STATUS status; + UINT i; + PNDIS_RESOURCE_LIST resourceList; + UINT resourceListSize; + + // + // Make sure the medium is supported + // + for (i = 0; i < MediumArraySize; i++) + { + if (MediumArray[i] == NdisMedium802_3) + { + *SelectedMediumIndex = i; + break; + } + } + + if (i == MediumArraySize) + { + NDIS_DbgPrint(MIN_TRACE, ("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), + ADAPTER_TAG); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Failed to allocate adapter context\n")); + return NDIS_STATUS_RESOURCES; + } + + RtlZeroMemory(adapter, sizeof(*adapter)); + adapter->MiniportAdapterHandle = MiniportAdapterHandle; + NdisAllocateSpinLock(&adapter->Lock); + + // + // 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 + // + resourceList = NULL; + resourceListSize = 0; + NdisMQueryAdapterResources(&status, + WrapperConfigurationContext, + resourceList, + &resourceListSize); + if (status != NDIS_STATUS_RESOURCES) + { + NDIS_DbgPrint(MIN_TRACE, ("Unexpected failure of NdisMQueryAdapterResources #1\n")); + status = NDIS_STATUS_FAILURE; + goto Cleanup; + } + + status = NdisAllocateMemoryWithTag((PVOID*)&resourceList, + resourceListSize, + RESOURCE_LIST_TAG); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Failed to allocate resource list\n")); + goto Cleanup; + } + + NdisMQueryAdapterResources(&status, + WrapperConfigurationContext, + resourceList, + &resourceListSize); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unexpected failure of NdisMQueryAdapterResources #2\n")); + goto Cleanup; + } + + ASSERT(resourceList->Version == 1); + ASSERT(resourceList->Revision == 1); + + for (i = 0; i < resourceList->Count; i++) + { + switch (resourceList->PartialDescriptors[i].Type) + { + case CmResourceTypePort: + ASSERT(adapter->IoRangeStart == 0); + + ASSERT(resourceList->PartialDescriptors[i].u.Port.Start.HighPart == 0); + + adapter->IoRangeStart = resourceList->PartialDescriptors[i].u.Port.Start.LowPart; + adapter->IoRangeLength = resourceList->PartialDescriptors[i].u.Port.Length; + + NDIS_DbgPrint(MID_TRACE, ("I/O port range is %p to %p\n", + adapter->IoRangeStart, adapter->IoRangeStart + adapter->IoRangeLength)); + break; + + case CmResourceTypeInterrupt: + ASSERT(adapter->InterruptVector == 0); + ASSERT(adapter->InterruptLevel == 0); + + adapter->InterruptVector = resourceList->PartialDescriptors[i].u.Interrupt.Vector; + adapter->InterruptLevel = resourceList->PartialDescriptors[i].u.Interrupt.Level; + adapter->InterruptShared = (resourceList->PartialDescriptors[i].ShareDisposition == CmResourceShareShared); + adapter->InterruptFlags = resourceList->PartialDescriptors[i].Flags; + + NDIS_DbgPrint(MID_TRACE, ("IRQ vector is %d\n", adapter->InterruptVector)); + break; + + default: + NDIS_DbgPrint(MIN_TRACE, ("Unrecognized resource type: 0x%x\n", resourceList->PartialDescriptors[i].Type)); + break; + } + } + + NdisFreeMemory(resourceList, resourceListSize, 0); + resourceList = NULL; + + if (adapter->IoRangeStart == 0 || adapter->InterruptVector == 0) + { + NDIS_DbgPrint(MIN_TRACE, ("Adapter didn't receive enough resources\n")); + goto Cleanup; + } + + // + // Allocate the DMA resources + // + status = NdisMInitializeScatterGatherDma(MiniportAdapterHandle, + FALSE, // RTL8139 only supports 32-bit addresses + MAXIMUM_FRAME_SIZE); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to configure DMA\n")); + goto Cleanup; + } + + adapter->ReceiveBufferLength = FULL_RECEIVE_BUFFER_SIZE; + NdisMAllocateSharedMemory(MiniportAdapterHandle, + adapter->ReceiveBufferLength, + FALSE, + (PVOID*)&adapter->ReceiveBuffer, + &adapter->ReceiveBufferPa); + if (adapter->ReceiveBuffer == NULL) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to allocate receive buffer\n")); + goto Cleanup; + } + + NdisMAllocateSharedMemory(MiniportAdapterHandle, + MINIMUM_FRAME_SIZE * TX_DESC_COUNT, + FALSE, + (PVOID*)&adapter->RuntTxBuffers, + &adapter->RuntTxBuffersPa); + if (adapter->RuntTxBuffers == NULL) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to allocate runt TX buffer\n")); + goto Cleanup; + } + + // + // Register the I/O port range and configure the NIC + // + status = NdisMRegisterIoPortRange((PVOID*)&adapter->IoBase, + MiniportAdapterHandle, + adapter->IoRangeStart, + adapter->IoRangeLength); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to register IO port range (0x%x)\n", status)); + goto Cleanup; + } + + // + // Adapter setup + // + status = NICPowerOn(adapter); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to power on NIC (0x%x)\n", status)); + goto Cleanup; + } + + status = NICSoftReset(adapter); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to reset the NIC (0x%x)\n", status)); + goto Cleanup; + } + + status = NICGetPermanentMacAddress(adapter, adapter->PermanentMacAddress); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to get the fixed MAC address (0x%x)\n", status)); + goto Cleanup; + } + + RtlCopyMemory(adapter->CurrentMacAddress, adapter->PermanentMacAddress, IEEE_802_ADDR_LENGTH); + + // + // Update link state and speed + // + NICUpdateLinkStatus(adapter); + + status = NICRegisterReceiveBuffer(adapter); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to setup receive buffer (0x%x)\n", status)); + goto Cleanup; + } + + // + // We're ready to handle interrupts now + // + status = NdisMRegisterInterrupt(&adapter->Interrupt, + 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) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to register interrupt (0x%x)\n", status)); + goto Cleanup; + } + + adapter->InterruptRegistered = TRUE; + + // + // Enable interrupts on the NIC + // + adapter->InterruptMask = DEFAULT_INTERRUPT_MASK; + status = NICApplyInterruptMask(adapter); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to apply interrupt mask (0x%x)\n", status)); + goto Cleanup; + } + + // + // Turn on TX and RX now + // + status = NICEnableTxRx(adapter); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to enable TX and RX (0x%x)\n", status)); + goto Cleanup; + } + + return NDIS_STATUS_SUCCESS; + +Cleanup: + if (resourceList != NULL) + { + NdisFreeMemory(resourceList, resourceListSize, 0); + } + if (adapter != NULL) + { + MiniportHalt(adapter); + } + + return status; +} + +NTSTATUS +NTAPI +DriverEntry ( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ) +{ + NDIS_HANDLE wrapperHandle; + NDIS_MINIPORT_CHARACTERISTICS characteristics; + NDIS_STATUS status; + + RtlZeroMemory(&characteristics, sizeof(characteristics)); + 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; +} +
Propchange: trunk/reactos/drivers/network/dd/rtl8139/ndis.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/network/dd/rtl8139/nic.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/dd/rtl8139/... ============================================================================== --- trunk/reactos/drivers/network/dd/rtl8139/nic.h (added) +++ trunk/reactos/drivers/network/dd/rtl8139/nic.h [iso-8859-1] Fri Jul 5 04:18:32 2013 @@ -0,0 +1,204 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Realtek 8139 driver + * FILE: rtl8139.h + * PURPOSE: RTL8139 driver definitions + */ + +#include <ndis.h> +#include <rtlhw.h> + +#define ADAPTER_TAG 'Altr' +#define RESOURCE_LIST_TAG 'Rltr' + +#define MAX_RESET_ATTEMPTS 25 +#define MAX_RECEIVES_PER_INT 10 +#define RECEIVE_BUFFER_SIZE (32768) +#define FULL_RECEIVE_BUFFER_SIZE (32768 + 16 + 2048) +#define RECV_CRC_LENGTH 4 + +#define MINIMUM_FRAME_SIZE 60 +#define MAXIMUM_FRAME_SIZE 1514 + +#define DRIVER_VERSION 1 + +// 32K RX buffer, 512 byte DMA bursts +#define RC_VAL (0x0001680) + +// 1024 byte DMA bursts +#define TC_VAL (0x600) + +typedef struct _RTL_ADAPTER { + NDIS_HANDLE MiniportAdapterHandle; + NDIS_SPIN_LOCK Lock; + + ULONG IoRangeStart; + ULONG IoRangeLength; + + ULONG InterruptVector; + ULONG InterruptLevel; + BOOLEAN InterruptShared; + ULONG InterruptFlags; + + PUCHAR IoBase; + NDIS_MINIPORT_INTERRUPT Interrupt; + BOOLEAN InterruptRegistered; + + UCHAR PermanentMacAddress[IEEE_802_ADDR_LENGTH]; + UCHAR CurrentMacAddress[IEEE_802_ADDR_LENGTH]; + struct { + UCHAR MacAddress[IEEE_802_ADDR_LENGTH]; + } MulticastList[MAXIMUM_MULTICAST_ADDRESSES]; + + ULONG ReceiveBufferLength; + PUCHAR ReceiveBuffer; + NDIS_PHYSICAL_ADDRESS ReceiveBufferPa; + USHORT ReceiveOffset; + + ULONG LinkSpeedMbps; + ULONG MediaState; + BOOLEAN LinkChange; + + ULONG PacketFilter; + + USHORT InterruptMask; + USHORT InterruptPending; + + UCHAR DirtyTxDesc; + UCHAR CurrentTxDesc; + BOOLEAN TxFull; + PUCHAR RuntTxBuffers; + NDIS_PHYSICAL_ADDRESS RuntTxBuffersPa; + + ULONG ReceiveOk; + ULONG TransmitOk; + ULONG ReceiveError; + ULONG TransmitError; + ULONG ReceiveNoBufferSpace; + ULONG ReceiveCrcError; + ULONG ReceiveAlignmentError; + ULONG TransmitOneCollision; + ULONG TransmitMoreCollisions; + +} RTL_ADAPTER, *PRTL_ADAPTER; + +NDIS_STATUS +NTAPI +NICPowerOn ( + IN PRTL_ADAPTER Adapter + ); + +NDIS_STATUS +NTAPI +NICSoftReset ( + IN PRTL_ADAPTER Adapter + ); + +NDIS_STATUS +NTAPI +NICRegisterReceiveBuffer ( + IN PRTL_ADAPTER Adapter + ); + +NDIS_STATUS +NTAPI +NICRemoveReceiveBuffer ( + IN PRTL_ADAPTER Adapter + ); + +NDIS_STATUS +NTAPI +NICEnableTxRx ( + IN PRTL_ADAPTER Adapter + ); + +NDIS_STATUS +NTAPI +NICGetPermanentMacAddress ( + IN PRTL_ADAPTER Adapter, + OUT PUCHAR MacAddress + ); + +NDIS_STATUS +NTAPI +NICApplyPacketFilter ( + IN PRTL_ADAPTER Adapter + ); + +NDIS_STATUS +NTAPI +NICApplyInterruptMask ( + IN PRTL_ADAPTER Adapter + ); + +NDIS_STATUS +NTAPI +NICDisableInterrupts ( + IN PRTL_ADAPTER Adapter + ); + +USHORT +NTAPI +NICInterruptRecognized ( + IN PRTL_ADAPTER Adapter, + OUT PBOOLEAN InterruptRecognized + ); + +VOID +NTAPI +NICAcknowledgeInterrupts ( + IN PRTL_ADAPTER Adapter + ); + +VOID +NTAPI +NICUpdateLinkStatus ( + IN PRTL_ADAPTER Adapter + ); + +NDIS_STATUS +NTAPI +NICTransmitPacket ( + IN PRTL_ADAPTER Adapter, + IN UCHAR TxDesc, + IN ULONG PhysicalAddress, + IN ULONG Length + ); + +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 + ); + +VOID +NTAPI +MiniportISR ( + OUT PBOOLEAN InterruptRecognized, + OUT PBOOLEAN QueueMiniportHandleInterrupt, + IN NDIS_HANDLE MiniportAdapterContext + ); + +VOID +NTAPI +MiniportHandleInterrupt ( + IN NDIS_HANDLE MiniportAdapterContext + ); + +/* EOF */
Propchange: trunk/reactos/drivers/network/dd/rtl8139/nic.h ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/network/dd/rtl8139/rtl8139.rc URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/dd/rtl8139/... ============================================================================== --- trunk/reactos/drivers/network/dd/rtl8139/rtl8139.rc (added) +++ trunk/reactos/drivers/network/dd/rtl8139/rtl8139.rc [iso-8859-1] Fri Jul 5 04:18:32 2013 @@ -0,0 +1,6 @@ + +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "Realtek 8139 Ethernet Driver\0" +#define REACTOS_STR_INTERNAL_NAME "rtl8139\0" +#define REACTOS_STR_ORIGINAL_FILENAME "rtl8139.sys\0" +#include <reactos/version.rc>
Propchange: trunk/reactos/drivers/network/dd/rtl8139/rtl8139.rc ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/network/dd/rtl8139/rtlhw.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/dd/rtl8139/... ============================================================================== --- trunk/reactos/drivers/network/dd/rtl8139/rtlhw.h (added) +++ trunk/reactos/drivers/network/dd/rtl8139/rtlhw.h [iso-8859-1] Fri Jul 5 04:18:32 2013 @@ -0,0 +1,169 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS RTL8139 Driver + * FILE: rtlhw.h + * PURPOSE: 8139 NIC definitions + */ + +#pragma once + +#define MAXIMUM_MULTICAST_ADDRESSES 8 +#define DEFAULT_INTERRUPT_MASK (R_I_RXOK | R_I_RXERR | R_I_TXOK | \ + R_I_TXERR | R_I_RXOVRFLW | R_I_RXUNDRUN | \ + R_I_FIFOOVR | R_I_PCSTMOUT | R_I_PCIERR) +#define TX_DESC_COUNT 4 + +//Register addresses +#define R_MAC 0x00 //MAC address uses bytes 0-5, 6 and 7 are reserved +#define R_MCAST0 0x08 //Multicast registers +#define R_MCAST1 0x09 //Multicast registers +#define R_MCAST2 0x0A +#define R_MCAST3 0x0B +#define R_MCAST4 0x0C +#define R_MCAST5 0x0D +#define R_MCAST6 0x0E +#define R_MCAST7 0x0F +#define R_TXSTS0 0x10 //TX status, 0x10-0x13, 4 bytes +#define R_TXSTS1 0x14 +#define R_TXSTS2 0x18 +#define R_TXSTS3 0x1C +#define R_TXSAD0 0x20 //TX start address of descriptor 0 +#define R_TXSAD1 0x24 +#define R_TXSAD2 0x28 +#define R_TXSAD3 0x2C +#define R_RXSA 0x30 //RX buffer start address +#define R_ERXBC 0x34 //Early RX byte count register +#define R_ERXSTS 0x36 //Early RX status register + +#define R_TXS_HOSTOWNS 0x00002000 //Driver still owns the buffer +#define R_TXS_UNDERRUN 0x00004000 //TX underrun +#define R_TXS_STATOK 0x00008000 //Successful TX +#define R_TXS_OOW 0x20000000 //Out of window +#define R_TXS_ABORTED 0x40000000 //TX aborted +#define R_TXS_CARLOST 0x80000000 //Carrier lost + +#define R_CMD 0x37 //Command register +#define R_CMD_RXEMPTY 0x01 //Receive buffer empty +#define B_CMD_TXE 0x04 //Enable TX +#define B_CMD_RXE 0x08 //Enable RX +#define B_CMD_RST 0x10 //Reset bit + +#define R_CAPR 0x38 //Current address of packet read +#define R_CBA 0x3A //Current buffer address +#define R_IM 0x3C //Interrupt mask register +#define R_IS 0x3E //Interrupt status register +#define R_TC 0x40 //Transmit configuration register + +#define R_I_RXOK 0x0001 //Receive OK +#define R_I_RXERR 0x0002 //Receive error +#define R_I_TXOK 0x0004 //Transmit OK +#define R_I_TXERR 0x0008 //Trasmit error +#define R_I_RXOVRFLW 0x0010 //Receive overflow +#define R_I_RXUNDRUN 0x0020 //Receive underrun +#define R_I_FIFOOVR 0x0040 //FIFO overflow +#define R_I_PCSTMOUT 0x4000 //PCS timeout +#define R_I_PCIERR 0x8000 //PCI error + +#define R_RC 0x44 //Receive configuration register +#define B_RC_AAP 0x01 //Accept all packets +#define B_RC_APM 0x02 //Accept packets sent to device MAC +#define B_RC_AM 0x04 //Accept multicast packets +#define B_RC_AB 0x08 //Accept broadcast packets +#define B_RC_AR 0x10 //Accept runt (smaller than 64bytes) packets + +#define R_TCTR 0x48 //Timer counter register +#define R_MPC 0x4C //Missed packet counter +#define R_9346CR 0x50 //93C46 command register +#define R_CFG0 0x51 //Configuration register 0 +#define R_CFG1 0x52 +#define R_TINTR 0x54 //Timer interrupt register +#define R_MS 0x58 //Media status register + +#define R_MS_LINKDWN 0x04 //Link is down +#define R_MS_SPEED_10 0x08 //Media is at 10mbps + +#define R_CFG3 0x59 //Configuration register 3 +#define R_CFG4 0x5A //Configuration register 4 +#define R_MINTS 0x5C //Multiple interrupt select +#define R_PCIID 0x5E //PCI Revision ID = 0x10 +#define R_DTSTS 0x60 //TX status of all descriptors +#define R_BMC 0x62 //Basic mode control register +#define R_BMSTS 0x64 //Basic mode status register +#define R_ANA 0x66 //Auto-negotiation advertisement +#define R_ANLP 0x68 //Auto-negotiation link partner +#define R_ANEX 0x6A //Auto-negotiation expansion +#define R_DCTR 0x6C //Disconnect counter +#define R_FCSCTR 0x6E //False carrier sense counter +#define R_NWT 0x70 //N-way test register +#define R_RXERRCTR 0x72 //RX error counter +#define R_CSCFG 0x74 //CS configuration register + +#define R_CSCR_LINKOK 0x00400 //Link up +#define R_CSCR_LINKCHNG 0x00800 //Link changed + +#define R_PHYP1 0x78 //PHY parameter 1 +#define R_TWP 0x7C //Twister parameter +#define R_PHYP2 0x80 //PHY parameter 2 +#define R_PCRC0 0x84 //Power management CRC for wakeup frame 0 +#define R_PCRC1 0x85 +#define R_PCRC2 0x86 +#define R_PCRC3 0x87 +#define R_PCRC4 0x88 +#define R_PCRC5 0x89 +#define R_PCRC6 0x8A +#define R_PCRC7 0x8B +#define R_WAKE0 0x8C //Power management wakeup frame 0 +#define R_WAKE1 0x94 +#define R_WAKE2 0x9C +#define R_WAKE3 0xA4 +#define R_WAKE4 0xAC +#define R_WAKE5 0xB4 +#define R_WAKE6 0xBC +#define R_WAKE7 0xC4 +#define R_LSBCRC0 0xCC //LSB of the mask byte of wakeup frame 0 within offset 12 to 75 +#define R_LSBCRC1 0xCD +#define R_LSBCRC2 0xCE +#define R_LSBCRC3 0xCF +#define R_LSBCRC4 0xD0 +#define R_LSBCRC5 0xD1 +#define R_LSBCRC6 0xD2 +#define R_LSBCRC7 0xD3 +#define R_CFG5 0xD8 //Configuration register 5 + +//EEPROM Control Bytes +#define EE_DATA_READ 0x01 //Chip data out +#define EE_DATA_WRITE 0x02 //Chip data in +#define EE_SHIFT_CLK 0x04 //Chip shift clock +#define EE_CS 0x08 //Chip select +#define EE_ENB 0x88 //Chip enable + + +//EEPROM Commands +#define EE_READ_CMD 0x06 + +#define RSR_MAR 0x8000 //Mulicast receive +#define RSR_PAM 0x4000 //Physical address match (directed packet) +#define RSR_BAR 0x2000 //Broadcast receive +#define RSR_ISE 0x0020 //Invalid symbol +#define RSR_RUNT 0x0010 //Runt packet +#define RSR_LONG 0x0008 //Long packet +#define RSR_CRC 0x0004 //CRC error +#define RSR_FAE 0x0002 //Frame alignment error +#define RSR_ROK 0x0001 //Receive OK + +/* NIC prepended structure to a received packet */ +typedef struct _PACKET_HEADER { + USHORT Status; /* See RSR_* constants */ + USHORT PacketLength; /* Length of packet NOT including this header */ +} PACKET_HEADER, *PPACKET_HEADER; + +#define IEEE_802_ADDR_LENGTH 6 + +/* 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; + +/* EOF */
Propchange: trunk/reactos/drivers/network/dd/rtl8139/rtlhw.h ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/media/inf/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/media/inf/CMakeLists.txt?re... ============================================================================== --- trunk/reactos/media/inf/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/media/inf/CMakeLists.txt [iso-8859-1] Fri Jul 5 04:18:32 2013 @@ -27,6 +27,7 @@ NET_NIC.inf netamd.inf netisa.inf + netrtl.inf netrtpnt.inf nettcpip.inf ports.inf
Added: trunk/reactos/media/inf/netrtl.inf URL: http://svn.reactos.org/svn/reactos/trunk/reactos/media/inf/netrtl.inf?rev=59... ============================================================================== Binary file - no diff available.
Propchange: trunk/reactos/media/inf/netrtl.inf ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream