mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 10:45:24 +00:00
[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) svn path=/trunk/; revision=59427
This commit is contained in:
parent
3fb662667c
commit
50c8f14805
|
@ -1,3 +1,4 @@
|
|||
|
||||
add_subdirectory(ne2000)
|
||||
add_subdirectory(pcnet)
|
||||
add_subdirectory(rtl8139)
|
||||
|
|
18
reactos/drivers/network/dd/rtl8139/CMakeLists.txt
Normal file
18
reactos/drivers/network/dd/rtl8139/CMakeLists.txt
Normal file
|
@ -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)
|
235
reactos/drivers/network/dd/rtl8139/hardware.c
Normal file
235
reactos/drivers/network/dd/rtl8139/hardware.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -1,247 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Novell Eagle 2000 driver
|
||||
* FILE: include/ne2000.h
|
||||
* PURPOSE: NE2000 driver definitions
|
||||
*/
|
||||
|
||||
#define NDIS_MINIPORT_DRIVER 1
|
||||
#define NDIS_LEGACY_MINIPORT 1
|
||||
#define NDIS51_MINIPORT 1
|
||||
#include <ndis.h>
|
||||
#include <8139.h>
|
||||
#include <debug.h>
|
||||
|
||||
/* Define NOCARD to test NDIS without a card */
|
||||
//#define NOCARD
|
||||
|
||||
/* NE2000 sepcific constants */
|
||||
#define NIC_DATA 0x10 /* Data register */
|
||||
#define NIC_RESET 0x1F /* Reset register */
|
||||
|
||||
|
||||
/* Global constants */
|
||||
|
||||
#define DRIVER_NDIS_MAJOR_VERSION 0x05
|
||||
#define DRIVER_NDIS_MINOR_VERSION 0
|
||||
|
||||
#define DRIVER_DEFAULT_IO_BASE_ADDRESS 0x280 /* bochs default */
|
||||
#define DRIVER_DEFAULT_INTERRUPT_NUMBER 9 /* bochs default */
|
||||
#define DRIVER_DEFAULT_INTERRUPT_SHARED FALSE
|
||||
#define DRIVER_DEFAULT_INTERRUPT_MODE NdisInterruptLatched
|
||||
|
||||
#define DRIVER_MAX_MULTICAST_LIST_SIZE 8
|
||||
|
||||
#define DRIVER_VENDOR_DESCRIPTION "RTL 8139 Adapter."
|
||||
#define DRIVER_VENDOR_DRIVER_VERSION 0x0100 /* 1.0 */
|
||||
|
||||
#define DRIVER_FRAME_SIZE 1514 /* Size of an ethernet frame */
|
||||
#define DRIVER_HEADER_SIZE 14 /* Size of an ethernet header */
|
||||
#define DRIVER_LENGTH_OF_ADDRESS 6 /* Size of an ethernet address */
|
||||
|
||||
/* Maximum lookahead buffer size */
|
||||
#define DRIVER_MAXIMUM_LOOKAHEAD (252 - DRIVER_HEADER_SIZE)
|
||||
|
||||
/* Size of a block in a buffer ring */
|
||||
#define DRIVER_BLOCK_SIZE 256
|
||||
|
||||
|
||||
/* Default number of transmit buffers */
|
||||
#define DRIVER_DEFAULT_TX_BUFFER_COUNT 12
|
||||
#define BUFFERS_PER_TX_BUF 1
|
||||
|
||||
/* Interrupt Mask Register value */
|
||||
#define DRIVER_INTERRUPT_MASK IMR_ALLE - IMR_RDCE
|
||||
|
||||
/* Maximum number of interrupts handled per call to MiniportHandleInterrupt */
|
||||
#define INTERRUPT_LIMIT 10
|
||||
|
||||
/* Global structures */
|
||||
|
||||
typedef struct _MINIPORT_RESERVED
|
||||
{
|
||||
PNDIS_PACKET Next;
|
||||
} MINIPORT_RESERVED, *PMINIPORT_RESERVED;
|
||||
|
||||
#define RESERVED(Packet) ((PMINIPORT_RESERVED)((Packet)->MiniportReserved))
|
||||
|
||||
typedef UCHAR DRIVER_HARDWARE_ADDRESS[DRIVER_LENGTH_OF_ADDRESS];
|
||||
|
||||
/* Information about an adapter */
|
||||
typedef struct _NIC_ADAPTER
|
||||
{
|
||||
/* Entry on global adapter list */
|
||||
LIST_ENTRY ListEntry;
|
||||
/* Adapter handle */
|
||||
NDIS_HANDLE MiniportAdapterHandle;
|
||||
/* NDIS interrupt object */
|
||||
NDIS_MINIPORT_INTERRUPT Interrupt;
|
||||
|
||||
/* I/O base address and interrupt number of adapter */
|
||||
ULONG_PTR IoBaseAddress;
|
||||
ULONG InterruptLevel;
|
||||
ULONG InterruptVector;
|
||||
BOOLEAN InterruptShared;
|
||||
KINTERRUPT_MODE InterruptMode;
|
||||
|
||||
/* Mapped address of the I/O base port */
|
||||
PUCHAR IOBase;
|
||||
|
||||
/* TRUE if the NIC can transfer in word mode */
|
||||
BOOLEAN WordMode;
|
||||
|
||||
/* Base address and size of the onboard memory window */
|
||||
PUCHAR RamBase;
|
||||
UINT RamSize;
|
||||
|
||||
/* Station Address PROM (SAPROM) */
|
||||
UCHAR SAPROM[16];
|
||||
|
||||
/* Onboard ethernet address from the manufacturer */
|
||||
DRIVER_HARDWARE_ADDRESS PermanentAddress;
|
||||
|
||||
/* Ethernet address currently in use */
|
||||
DRIVER_HARDWARE_ADDRESS StationAddress;
|
||||
|
||||
/* Maximum number of multicast addresses this adapter supports */
|
||||
ULONG MaxMulticastListSize;
|
||||
|
||||
/* List of multicast addresses in use */
|
||||
DRIVER_HARDWARE_ADDRESS Addresses[DRIVER_MAX_MULTICAST_LIST_SIZE];
|
||||
|
||||
/* Current multicast address mask */
|
||||
UCHAR MulticastAddressMask[8];
|
||||
|
||||
/* Masked interrupts (IMR value) */
|
||||
ULONG InterruptMask;
|
||||
|
||||
/* Interrupts that have occurred */
|
||||
UCHAR InterruptStatus;
|
||||
|
||||
/* Current packet filter */
|
||||
ULONG PacketFilter;
|
||||
|
||||
/* Lookahead buffer */
|
||||
UINT LookaheadSize;
|
||||
UCHAR Lookahead[DRIVER_MAXIMUM_LOOKAHEAD + DRIVER_HEADER_SIZE];
|
||||
|
||||
/* Receive buffer ring */
|
||||
UINT PageStart;
|
||||
UINT PageStop;
|
||||
UINT CurrentPage;
|
||||
UINT NextPacket;
|
||||
|
||||
/* TRUE if there was a buffer overflow */
|
||||
BOOLEAN BufferOverflow;
|
||||
|
||||
/* TRUE if an error occurred during reception of a packet */
|
||||
BOOLEAN ReceiveError;
|
||||
|
||||
/* TRUE if an error occurred during transmission of a packet */
|
||||
BOOLEAN TransmitError;
|
||||
|
||||
/* TRUE if a transmit interrupt is pending */
|
||||
BOOLEAN TransmitPending;
|
||||
|
||||
/* Received packet header */
|
||||
PACKET_HEADER PacketHeader;
|
||||
|
||||
/* Offset in onboard RAM of received packet */
|
||||
ULONG PacketOffset;
|
||||
|
||||
/* TRUE if receive indications are done and should be completed */
|
||||
BOOLEAN DoneIndicating;
|
||||
|
||||
/* Transmit buffers */
|
||||
UINT TXStart; /* Start block of transmit buffer ring */
|
||||
UINT TXCount; /* Number of blocks in transmit buffer ring */
|
||||
UINT TXFree; /* Number of free transmit buffers */
|
||||
UINT TXNext; /* Next buffer to use */
|
||||
/* Length of packet. 0 means buffer is unused */
|
||||
UINT TXSize[DRIVER_DEFAULT_TX_BUFFER_COUNT];
|
||||
INT TXCurrent; /* Current buffer beeing transmitted. -1 means none */
|
||||
|
||||
/* Head of transmit queue */
|
||||
PNDIS_PACKET TXQueueHead;
|
||||
/* Tail of transmit queue */
|
||||
PNDIS_PACKET TXQueueTail;
|
||||
|
||||
/* Statistics */
|
||||
ULONG FrameAlignmentErrors;
|
||||
ULONG CrcErrors;
|
||||
ULONG MissedPackets;
|
||||
|
||||
/* Flags used for driver cleanup */
|
||||
BOOLEAN IOPortRangeRegistered;
|
||||
BOOLEAN InterruptRegistered;
|
||||
BOOLEAN ShutdownHandlerRegistered;
|
||||
} NIC_ADAPTER, *PNIC_ADAPTER;
|
||||
|
||||
/* Global driver information */
|
||||
typedef struct _DRIVER_INFORMATION
|
||||
{
|
||||
NDIS_HANDLE NdisWrapperHandle; /* Returned from NdisInitializeWrapper */
|
||||
NDIS_HANDLE NdisMacHandle; /* Returned from NdisRegisterMac */
|
||||
LIST_ENTRY AdapterListHead; /* Adapters this driver control */
|
||||
} DRIVER_INFORMATION, *PDRIVER_INFORMATION;
|
||||
|
||||
|
||||
|
||||
/* Global variable */
|
||||
|
||||
extern DRIVER_INFORMATION DriverInfo;
|
||||
extern NDIS_PHYSICAL_ADDRESS HighestAcceptableMax;
|
||||
|
||||
|
||||
|
||||
/* Prototypes */
|
||||
|
||||
BOOLEAN NICCheck(
|
||||
PNIC_ADAPTER Adapter);
|
||||
|
||||
NDIS_STATUS NICInitialize(
|
||||
PNIC_ADAPTER Adapter);
|
||||
|
||||
NDIS_STATUS NICSetup(
|
||||
PNIC_ADAPTER Adapter);
|
||||
|
||||
NDIS_STATUS NICStart(
|
||||
PNIC_ADAPTER Adapter);
|
||||
|
||||
NDIS_STATUS NICStop(
|
||||
PNIC_ADAPTER Adapter);
|
||||
|
||||
NDIS_STATUS NICReset(
|
||||
PNIC_ADAPTER Adapter);
|
||||
|
||||
VOID NICUpdateCounters(
|
||||
PNIC_ADAPTER Adapter);
|
||||
|
||||
VOID NICReadDataAlign(
|
||||
PNIC_ADAPTER Adapter,
|
||||
PUSHORT Target,
|
||||
ULONG_PTR Source,
|
||||
USHORT Length);
|
||||
|
||||
VOID NICWriteDataAlign(
|
||||
PNIC_ADAPTER Adapter,
|
||||
ULONG_PTR Target,
|
||||
PUSHORT Source,
|
||||
USHORT Length);
|
||||
|
||||
VOID NICReadData(
|
||||
PNIC_ADAPTER Adapter,
|
||||
PUCHAR Target,
|
||||
ULONG_PTR Source,
|
||||
USHORT Length);
|
||||
|
||||
VOID NICWriteData(
|
||||
PNIC_ADAPTER Adapter,
|
||||
ULONG_PTR Target,
|
||||
PUCHAR Source,
|
||||
USHORT Length);
|
||||
|
||||
VOID NICTransmit(
|
||||
PNIC_ADAPTER Adapter);
|
||||
|
||||
/* EOF */
|
394
reactos/drivers/network/dd/rtl8139/info.c
Normal file
394
reactos/drivers/network/dd/rtl8139/info.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
210
reactos/drivers/network/dd/rtl8139/interrupt.c
Normal file
210
reactos/drivers/network/dd/rtl8139/interrupt.c
Normal file
|
@ -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);
|
||||
}
|
||||
|
525
reactos/drivers/network/dd/rtl8139/ndis.c
Normal file
525
reactos/drivers/network/dd/rtl8139/ndis.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
204
reactos/drivers/network/dd/rtl8139/nic.h
Normal file
204
reactos/drivers/network/dd/rtl8139/nic.h
Normal file
|
@ -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 */
|
6
reactos/drivers/network/dd/rtl8139/rtl8139.rc
Normal file
6
reactos/drivers/network/dd/rtl8139/rtl8139.rc
Normal file
|
@ -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>
|
|
@ -1,11 +1,18 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS RTL8139 Driver
|
||||
* FILE: include/8139.h
|
||||
* 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
|
||||
|
@ -28,7 +35,15 @@
|
|||
#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
|
||||
|
@ -39,6 +54,16 @@
|
|||
#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
|
||||
|
@ -53,6 +78,10 @@
|
|||
#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
|
||||
|
@ -68,6 +97,10 @@
|
|||
#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
|
||||
|
@ -88,13 +121,13 @@
|
|||
#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_LSBCRC0 0xCD
|
||||
#define R_LSBCRC0 0xCE
|
||||
#define R_LSBCRC0 0xCF
|
||||
#define R_LSBCRC0 0xD0
|
||||
#define R_LSBCRC0 0xD1
|
||||
#define R_LSBCRC0 0xD2
|
||||
#define R_LSBCRC0 0xD3
|
||||
#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
|
||||
|
@ -108,12 +141,20 @@
|
|||
//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 {
|
||||
UCHAR Status; /* See RSR_* constants */
|
||||
UCHAR NextPacket; /* Pointer to next packet in chain */
|
||||
USHORT PacketLength; /* Length of packet including this 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
|
||||
|
@ -125,22 +166,4 @@ typedef struct _ETH_HEADER {
|
|||
USHORT PayloadType;
|
||||
} ETH_HEADER, *PETH_HEADER;
|
||||
|
||||
typedef struct _DISCARD_HEADER {
|
||||
PACKET_HEADER HWHeader;
|
||||
ETH_HEADER EthernetHeader;
|
||||
} DISCARD_HEADER, *PDISCARD_HEADER;
|
||||
|
||||
#define NICDisableInterrupts(Adapter) { \
|
||||
NDIS_DbgPrint(MAX_TRACE, ("NICDisableInterrupts()\n")); \
|
||||
NdisRawWritePortUchar((Adapter)->IOBase + PG0_IMR, 0x00); \
|
||||
}
|
||||
|
||||
#define NICEnableInterrupts(Adapter) { \
|
||||
NDIS_DbgPrint(MAX_TRACE, ("NICEnableInterrupts() Mask (0x%X)\n", (Adapter)->InterruptMask)); \
|
||||
NdisRawWritePortUchar((Adapter)->IOBase + PG0_IMR, (Adapter)->InterruptMask); \
|
||||
}
|
||||
|
||||
VOID NTAPI MiniportHandleInterrupt(
|
||||
IN NDIS_HANDLE MiniportAdapterContext);
|
||||
|
||||
/* EOF */
|
|
@ -27,6 +27,7 @@ list(APPEND INF_FILES
|
|||
NET_NIC.inf
|
||||
netamd.inf
|
||||
netisa.inf
|
||||
netrtl.inf
|
||||
netrtpnt.inf
|
||||
nettcpip.inf
|
||||
ports.inf
|
||||
|
|
BIN
reactos/media/inf/netrtl.inf
Normal file
BIN
reactos/media/inf/netrtl.inf
Normal file
Binary file not shown.
Loading…
Reference in a new issue