mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[E1000] Minor improvements (#3904)
- Add support for 64-bit counters (Intel gigabit NICs) - Properly handle OIDs - Check that the packet filter is not 0 - Performance increase
This commit is contained in:
parent
55a1c29341
commit
3f97671319
7 changed files with 274 additions and 246 deletions
|
@ -12,7 +12,8 @@ list(APPEND SOURCE
|
|||
nic.h
|
||||
e1000hw.h
|
||||
debug.c
|
||||
debug.h)
|
||||
debug.h
|
||||
send.c)
|
||||
|
||||
add_library(e1000 MODULE ${SOURCE} e1000.rc)
|
||||
add_pch(e1000 nic.h SOURCE)
|
||||
|
|
|
@ -53,32 +53,6 @@ static USHORT SupportedDevices[] =
|
|||
0x10B5, // Intel 82546GB Quad Copper KSP3
|
||||
};
|
||||
|
||||
|
||||
static ULONG E1000WriteFlush(IN PE1000_ADAPTER Adapter)
|
||||
{
|
||||
volatile ULONG Value;
|
||||
|
||||
NdisReadRegisterUlong(Adapter->IoBase + E1000_REG_STATUS, &Value);
|
||||
return Value;
|
||||
}
|
||||
|
||||
VOID NTAPI E1000WriteUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, IN ULONG Value)
|
||||
{
|
||||
NdisWriteRegisterUlong((PULONG)(Adapter->IoBase + Address), Value);
|
||||
}
|
||||
|
||||
VOID NTAPI E1000ReadUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, OUT PULONG Value)
|
||||
{
|
||||
NdisReadRegisterUlong((PULONG)(Adapter->IoBase + Address), Value);
|
||||
}
|
||||
|
||||
static VOID E1000WriteIoUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, IN ULONG Value)
|
||||
{
|
||||
NdisRawWritePortUlong((PULONG)(Adapter->IoPort), Address);
|
||||
E1000WriteFlush(Adapter);
|
||||
NdisRawWritePortUlong((PULONG)(Adapter->IoPort + 4), Value);
|
||||
}
|
||||
|
||||
static ULONG PacketFilterToMask(ULONG PacketFilter)
|
||||
{
|
||||
ULONG FilterMask = 0;
|
||||
|
@ -145,16 +119,11 @@ static BOOLEAN E1000ReadMdic(IN PE1000_ADAPTER Adapter, IN ULONG Address, USHORT
|
|||
ULONG Mdic;
|
||||
UINT n;
|
||||
|
||||
if (Address > MAX_PHY_REG_ADDRESS)
|
||||
{
|
||||
NDIS_DbgPrint(MIN_TRACE, ("PHY Address %d is invalid\n", Address));
|
||||
return 1;
|
||||
}
|
||||
ASSERT(Address <= MAX_PHY_REG_ADDRESS)
|
||||
|
||||
Mdic = (Address << E1000_MDIC_REGADD_SHIFT);
|
||||
Mdic |= (E1000_MDIC_PHYADD_GIGABIT << E1000_MDIC_PHYADD_SHIFT);
|
||||
Mdic |= E1000_MDIC_OP_READ;
|
||||
|
||||
E1000WriteUlong(Adapter, E1000_REG_MDIC, Mdic);
|
||||
|
||||
for (n = 0; n < MAX_PHY_READ_ATTEMPTS; n++)
|
||||
|
@ -725,6 +694,7 @@ NICUpdateMulticastList(
|
|||
UINT n;
|
||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
// FIXME: Use 'Adapter->MulticastListSize'? Check the datasheet
|
||||
for (n = 0; n < MAXIMUM_MULTICAST_ADDRESSES; ++n)
|
||||
{
|
||||
ULONG Ral = *(ULONG *)Adapter->MulticastList[n].MacAddress;
|
||||
|
@ -763,46 +733,6 @@ NICApplyPacketFilter(
|
|||
return NDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NDIS_STATUS
|
||||
NTAPI
|
||||
NICApplyInterruptMask(
|
||||
IN PE1000_ADAPTER Adapter)
|
||||
{
|
||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
E1000WriteUlong(Adapter, E1000_REG_IMS, Adapter->InterruptMask /*| 0x1F6DC*/);
|
||||
return NDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NDIS_STATUS
|
||||
NTAPI
|
||||
NICDisableInterrupts(
|
||||
IN PE1000_ADAPTER Adapter)
|
||||
{
|
||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
E1000WriteUlong(Adapter, E1000_REG_IMC, ~0);
|
||||
return NDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
NICInterruptRecognized(
|
||||
IN PE1000_ADAPTER Adapter,
|
||||
OUT PBOOLEAN InterruptRecognized)
|
||||
{
|
||||
ULONG Value;
|
||||
|
||||
/* Reading the interrupt acknowledges them */
|
||||
E1000ReadUlong(Adapter, E1000_REG_ICR, &Value);
|
||||
|
||||
*InterruptRecognized = (Value & Adapter->InterruptMask) != 0;
|
||||
|
||||
NDIS_DbgPrint(MAX_TRACE, ("NICInterruptRecognized(0x%x, 0x%x).\n", Value, *InterruptRecognized));
|
||||
|
||||
return (Value & Adapter->InterruptMask);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
NICUpdateLinkStatus(
|
||||
|
@ -819,36 +749,3 @@ NICUpdateLinkStatus(
|
|||
SpeedIndex = (DeviceStatus & E1000_STATUS_SPEEDMASK) >> E1000_STATUS_SPEEDSHIFT;
|
||||
Adapter->LinkSpeedMbps = SpeedValues[SpeedIndex];
|
||||
}
|
||||
|
||||
NDIS_STATUS
|
||||
NTAPI
|
||||
NICTransmitPacket(
|
||||
IN PE1000_ADAPTER Adapter,
|
||||
IN PHYSICAL_ADDRESS PhysicalAddress,
|
||||
IN ULONG Length)
|
||||
{
|
||||
volatile PE1000_TRANSMIT_DESCRIPTOR TransmitDescriptor;
|
||||
|
||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
TransmitDescriptor = Adapter->TransmitDescriptors + Adapter->CurrentTxDesc;
|
||||
TransmitDescriptor->Address = PhysicalAddress.QuadPart;
|
||||
TransmitDescriptor->Length = Length;
|
||||
TransmitDescriptor->ChecksumOffset = 0;
|
||||
TransmitDescriptor->Command = E1000_TDESC_CMD_RS | E1000_TDESC_CMD_IFCS | E1000_TDESC_CMD_EOP | E1000_TDESC_CMD_IDE;
|
||||
TransmitDescriptor->Status = 0;
|
||||
TransmitDescriptor->ChecksumStartField = 0;
|
||||
TransmitDescriptor->Special = 0;
|
||||
|
||||
Adapter->CurrentTxDesc = (Adapter->CurrentTxDesc + 1) % NUM_TRANSMIT_DESCRIPTORS;
|
||||
|
||||
E1000WriteUlong(Adapter, E1000_REG_TDT, Adapter->CurrentTxDesc);
|
||||
|
||||
if (Adapter->CurrentTxDesc == Adapter->LastTxDesc)
|
||||
{
|
||||
NDIS_DbgPrint(MID_TRACE, ("All TX descriptors are full now\n"));
|
||||
Adapter->TxFull = TRUE;
|
||||
}
|
||||
|
||||
return NDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <debug.h>
|
||||
|
||||
static ULONG SupportedOidList[] =
|
||||
static NDIS_OID SupportedOidList[] =
|
||||
{
|
||||
OID_GEN_SUPPORTED_LIST,
|
||||
OID_GEN_CURRENT_PACKET_FILTER,
|
||||
|
@ -37,14 +37,36 @@ static ULONG SupportedOidList[] =
|
|||
OID_802_3_PERMANENT_ADDRESS,
|
||||
OID_802_3_CURRENT_ADDRESS,
|
||||
OID_802_3_MAXIMUM_LIST_SIZE,
|
||||
|
||||
/* Statistics */
|
||||
OID_GEN_XMIT_OK,
|
||||
OID_GEN_RCV_OK,
|
||||
OID_GEN_XMIT_ERROR,
|
||||
OID_GEN_RCV_ERROR,
|
||||
OID_GEN_RCV_NO_BUFFER,
|
||||
|
||||
OID_PNP_CAPABILITIES,
|
||||
};
|
||||
|
||||
static
|
||||
ULONG64
|
||||
NICQueryStatisticCounter(
|
||||
_In_ PE1000_ADAPTER Adapter,
|
||||
_In_ NDIS_OID Oid)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
NDIS_STATUS
|
||||
NICFillPowerManagementCapabilities(
|
||||
_In_ PE1000_ADAPTER Adapter,
|
||||
_Out_ PNDIS_PNP_CAPABILITIES Capabilities)
|
||||
{
|
||||
/* TODO */
|
||||
return NDIS_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
NDIS_STATUS
|
||||
NTAPI
|
||||
|
@ -57,13 +79,20 @@ MiniportQueryInformation(
|
|||
OUT PULONG BytesNeeded)
|
||||
{
|
||||
PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext;
|
||||
ULONG genericUlong;
|
||||
ULONG copyLength;
|
||||
PVOID copySource;
|
||||
NDIS_STATUS status;
|
||||
union _GENERIC_INFORMATION
|
||||
{
|
||||
USHORT Ushort;
|
||||
ULONG Ulong;
|
||||
ULONG64 Ulong64;
|
||||
NDIS_MEDIUM Medium;
|
||||
NDIS_PNP_CAPABILITIES PmCapabilities;
|
||||
} GenericInfo;
|
||||
|
||||
status = NDIS_STATUS_SUCCESS;
|
||||
copySource = &genericUlong;
|
||||
copySource = &GenericInfo;
|
||||
copyLength = sizeof(ULONG);
|
||||
|
||||
switch (Oid)
|
||||
|
@ -74,20 +103,19 @@ MiniportQueryInformation(
|
|||
break;
|
||||
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
genericUlong = Adapter->PacketFilter;
|
||||
GenericInfo.Ulong = Adapter->PacketFilter;
|
||||
break;
|
||||
|
||||
case OID_GEN_HARDWARE_STATUS:
|
||||
UNIMPLEMENTED_DBGBREAK();
|
||||
genericUlong = (ULONG)NdisHardwareStatusReady; //FIXME
|
||||
GenericInfo.Ulong = (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);
|
||||
GenericInfo.Medium = NdisMedium802_3;
|
||||
copyLength = sizeof(NDIS_MEDIUM);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -96,31 +124,36 @@ MiniportQueryInformation(
|
|||
case OID_GEN_CURRENT_LOOKAHEAD:
|
||||
case OID_GEN_MAXIMUM_LOOKAHEAD:
|
||||
case OID_GEN_MAXIMUM_FRAME_SIZE:
|
||||
genericUlong = MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER);
|
||||
GenericInfo.Ulong = MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER);
|
||||
break;
|
||||
|
||||
case OID_802_3_MULTICAST_LIST:
|
||||
copySource = Adapter->MulticastList;
|
||||
copyLength = Adapter->MulticastListSize * IEEE_802_ADDR_LENGTH;
|
||||
break;
|
||||
|
||||
case OID_802_3_MAXIMUM_LIST_SIZE:
|
||||
genericUlong = MAXIMUM_MULTICAST_ADDRESSES;
|
||||
GenericInfo.Ulong = MAXIMUM_MULTICAST_ADDRESSES;
|
||||
break;
|
||||
|
||||
case OID_GEN_LINK_SPEED:
|
||||
genericUlong = Adapter->LinkSpeedMbps * 10000;
|
||||
GenericInfo.Ulong = Adapter->LinkSpeedMbps * 10000;
|
||||
break;
|
||||
|
||||
case OID_GEN_TRANSMIT_BUFFER_SPACE:
|
||||
genericUlong = MAXIMUM_FRAME_SIZE;
|
||||
GenericInfo.Ulong = MAXIMUM_FRAME_SIZE;
|
||||
break;
|
||||
|
||||
case OID_GEN_RECEIVE_BUFFER_SPACE:
|
||||
genericUlong = RECEIVE_BUFFER_SIZE;
|
||||
GenericInfo.Ulong = 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);
|
||||
GenericInfo.Ulong = 0;
|
||||
GenericInfo.Ulong |= (Adapter->PermanentMacAddress[0] << 16);
|
||||
GenericInfo.Ulong |= (Adapter->PermanentMacAddress[1] << 8);
|
||||
GenericInfo.Ulong |= (Adapter->PermanentMacAddress[2] & 0xFF);
|
||||
break;
|
||||
|
||||
case OID_GEN_VENDOR_DESCRIPTION:
|
||||
|
@ -132,38 +165,35 @@ MiniportQueryInformation(
|
|||
}
|
||||
|
||||
case OID_GEN_VENDOR_DRIVER_VERSION:
|
||||
genericUlong = DRIVER_VERSION;
|
||||
GenericInfo.Ulong = 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);
|
||||
copyLength = sizeof(USHORT);
|
||||
GenericInfo.Ushort = (NDIS_MINIPORT_MAJOR_VERSION << 8) + NDIS_MINIPORT_MINOR_VERSION;
|
||||
break;
|
||||
}
|
||||
|
||||
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
||||
genericUlong = MAXIMUM_FRAME_SIZE;
|
||||
GenericInfo.Ulong = MAXIMUM_FRAME_SIZE;
|
||||
break;
|
||||
|
||||
case OID_GEN_MAXIMUM_SEND_PACKETS:
|
||||
genericUlong = 1;
|
||||
GenericInfo.Ulong = 1;
|
||||
break;
|
||||
|
||||
case OID_GEN_MAC_OPTIONS:
|
||||
genericUlong = NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
|
||||
GenericInfo.Ulong = NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
|
||||
NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
|
||||
NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
|
||||
NDIS_MAC_OPTION_NO_LOOPBACK;
|
||||
break;
|
||||
|
||||
case OID_GEN_MEDIA_CONNECT_STATUS:
|
||||
genericUlong = Adapter->MediaState;
|
||||
GenericInfo.Ulong = Adapter->MediaState;
|
||||
break;
|
||||
|
||||
|
||||
case OID_802_3_CURRENT_ADDRESS:
|
||||
copySource = Adapter->MulticastList[0].MacAddress;
|
||||
copyLength = IEEE_802_ADDR_LENGTH;
|
||||
|
@ -175,20 +205,39 @@ MiniportQueryInformation(
|
|||
break;
|
||||
|
||||
case OID_GEN_XMIT_OK:
|
||||
genericUlong = 0;
|
||||
break;
|
||||
case OID_GEN_RCV_OK:
|
||||
genericUlong = 0;
|
||||
break;
|
||||
case OID_GEN_XMIT_ERROR:
|
||||
genericUlong = 0;
|
||||
break;
|
||||
case OID_GEN_RCV_ERROR:
|
||||
genericUlong = 0;
|
||||
break;
|
||||
case OID_GEN_RCV_NO_BUFFER:
|
||||
genericUlong = 0;
|
||||
{
|
||||
GenericInfo.Ulong64 = NICQueryStatisticCounter(Adapter, Oid);
|
||||
|
||||
*BytesNeeded = sizeof(ULONG64);
|
||||
if (InformationBufferLength >= sizeof(ULONG64))
|
||||
{
|
||||
*BytesWritten = sizeof(ULONG64);
|
||||
NdisMoveMemory(InformationBuffer, copySource, sizeof(ULONG64));
|
||||
}
|
||||
else if (InformationBufferLength >= sizeof(ULONG))
|
||||
{
|
||||
*BytesWritten = sizeof(ULONG);
|
||||
NdisMoveMemory(InformationBuffer, copySource, sizeof(ULONG));
|
||||
}
|
||||
else
|
||||
{
|
||||
*BytesWritten = 0;
|
||||
return NDIS_STATUS_BUFFER_TOO_SHORT;
|
||||
}
|
||||
return NDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
case OID_PNP_CAPABILITIES:
|
||||
{
|
||||
copyLength = sizeof(NDIS_PNP_CAPABILITIES);
|
||||
|
||||
status = NICFillPowerManagementCapabilities(Adapter, &GenericInfo.PmCapabilities);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NDIS_DbgPrint(MIN_TRACE, ("Unknown OID 0x%x(%s)\n", Oid, Oid2Str(Oid)));
|
||||
|
@ -202,7 +251,7 @@ MiniportQueryInformation(
|
|||
{
|
||||
*BytesNeeded = copyLength;
|
||||
*BytesWritten = 0;
|
||||
status = NDIS_STATUS_INVALID_LENGTH;
|
||||
status = NDIS_STATUS_BUFFER_TOO_SHORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -217,13 +266,8 @@ MiniportQueryInformation(
|
|||
*BytesNeeded = 0;
|
||||
}
|
||||
|
||||
/* XMIT_ERROR and RCV_ERROR are really noisy, so do not log those. */
|
||||
if (Oid != OID_GEN_XMIT_ERROR && Oid != OID_GEN_RCV_ERROR)
|
||||
{
|
||||
NDIS_DbgPrint(MAX_TRACE, ("Query OID 0x%x(%s): Completed with status 0x%x (%d, %d)\n",
|
||||
Oid, Oid2Str(Oid), status, *BytesWritten, *BytesNeeded));
|
||||
}
|
||||
|
||||
NDIS_DbgPrint(MAX_TRACE, ("Query OID 0x%x(%s): Completed with status 0x%x (%d, %d)\n",
|
||||
Oid, Oid2Str(Oid), status, *BytesWritten, *BytesNeeded));
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -257,12 +301,12 @@ MiniportSetInformation(
|
|||
NdisMoveMemory(&genericUlong, InformationBuffer, sizeof(ULONG));
|
||||
|
||||
if (genericUlong &
|
||||
(NDIS_PACKET_TYPE_SOURCE_ROUTING |
|
||||
NDIS_PACKET_TYPE_SMT |
|
||||
NDIS_PACKET_TYPE_ALL_LOCAL |
|
||||
NDIS_PACKET_TYPE_GROUP |
|
||||
NDIS_PACKET_TYPE_ALL_FUNCTIONAL |
|
||||
NDIS_PACKET_TYPE_FUNCTIONAL))
|
||||
~(NDIS_PACKET_TYPE_DIRECTED |
|
||||
NDIS_PACKET_TYPE_MULTICAST |
|
||||
NDIS_PACKET_TYPE_ALL_MULTICAST |
|
||||
NDIS_PACKET_TYPE_BROADCAST |
|
||||
NDIS_PACKET_TYPE_PROMISCUOUS |
|
||||
NDIS_PACKET_TYPE_MAC_FRAME))
|
||||
{
|
||||
*BytesRead = sizeof(ULONG);
|
||||
*BytesNeeded = sizeof(ULONG);
|
||||
|
@ -270,6 +314,11 @@ MiniportSetInformation(
|
|||
break;
|
||||
}
|
||||
|
||||
if (Adapter->PacketFilter == genericUlong)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Adapter->PacketFilter = genericUlong;
|
||||
|
||||
status = NICApplyPacketFilter(Adapter);
|
||||
|
@ -312,15 +361,18 @@ MiniportSetInformation(
|
|||
break;
|
||||
}
|
||||
|
||||
if (InformationBufferLength / 6 > MAXIMUM_MULTICAST_ADDRESSES)
|
||||
if (InformationBufferLength > sizeof(Adapter->MulticastList))
|
||||
{
|
||||
*BytesNeeded = MAXIMUM_MULTICAST_ADDRESSES * IEEE_802_ADDR_LENGTH;
|
||||
*BytesNeeded = sizeof(Adapter->MulticastList);
|
||||
*BytesRead = 0;
|
||||
status = NDIS_STATUS_INVALID_LENGTH;
|
||||
status = NDIS_STATUS_MULTICAST_FULL;
|
||||
break;
|
||||
}
|
||||
|
||||
NdisMoveMemory(Adapter->MulticastList, InformationBuffer, InformationBufferLength);
|
||||
|
||||
Adapter->MulticastListSize = InformationBufferLength / IEEE_802_ADDR_LENGTH;
|
||||
|
||||
NICUpdateMulticastList(Adapter);
|
||||
break;
|
||||
|
||||
|
|
|
@ -21,18 +21,24 @@ MiniportISR(
|
|||
ULONG Value;
|
||||
PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext;
|
||||
|
||||
Value = NICInterruptRecognized(Adapter, InterruptRecognized);
|
||||
InterlockedOr(&Adapter->InterruptPending, Value);
|
||||
/* Reading the interrupt acknowledges them */
|
||||
E1000ReadUlong(Adapter, E1000_REG_ICR, &Value);
|
||||
|
||||
if (!(*InterruptRecognized))
|
||||
Value &= Adapter->InterruptMask;
|
||||
_InterlockedOr(&Adapter->InterruptPending, Value);
|
||||
|
||||
if (Value)
|
||||
{
|
||||
*InterruptRecognized = TRUE;
|
||||
/* Mark the events pending service */
|
||||
*QueueMiniportHandleInterrupt = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is not ours. */
|
||||
*InterruptRecognized = FALSE;
|
||||
*QueueMiniportHandleInterrupt = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mark the events pending service */
|
||||
*QueueMiniportHandleInterrupt = TRUE;
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -46,7 +52,7 @@ MiniportHandleInterrupt(
|
|||
|
||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
InterruptPending = InterlockedExchange(&Adapter->InterruptPending, 0);
|
||||
InterruptPending = _InterlockedExchange(&Adapter->InterruptPending, 0);
|
||||
|
||||
|
||||
/* Link State Changed */
|
||||
|
@ -101,6 +107,12 @@ MiniportHandleInterrupt(
|
|||
NDIS_DbgPrint(MIN_TRACE, ("Unrecognized ReceiveDescriptor status flag: %u\n", ReceiveDescriptor->Status));
|
||||
}
|
||||
|
||||
/* Make sure the receive indications are enabled */
|
||||
if (!Adapter->PacketFilter)
|
||||
{
|
||||
goto NextReceiveDescriptor;
|
||||
}
|
||||
|
||||
if (ReceiveDescriptor->Length != 0 && ReceiveDescriptor->Address != 0)
|
||||
{
|
||||
EthHeader = (PETH_HEADER)(Adapter->ReceiveBuffer + BufferOffset);
|
||||
|
@ -120,6 +132,7 @@ MiniportHandleInterrupt(
|
|||
NDIS_DbgPrint(MIN_TRACE, ("Got a NULL descriptor"));
|
||||
}
|
||||
|
||||
NextReceiveDescriptor:
|
||||
/* Give the descriptor back */
|
||||
ReceiveDescriptor->Status = 0;
|
||||
|
||||
|
|
|
@ -23,44 +23,6 @@ MiniportReset(
|
|||
return NDIS_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
NDIS_STATUS
|
||||
NTAPI
|
||||
MiniportSend(
|
||||
IN NDIS_HANDLE MiniportAdapterContext,
|
||||
IN PNDIS_PACKET Packet,
|
||||
IN UINT Flags)
|
||||
{
|
||||
PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext;
|
||||
PSCATTER_GATHER_LIST sgList = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, ScatterGatherListPacketInfo);
|
||||
ULONG TransmitLength;
|
||||
PHYSICAL_ADDRESS TransmitBuffer;
|
||||
NDIS_STATUS Status;
|
||||
|
||||
ASSERT(sgList != NULL);
|
||||
ASSERT(sgList->NumberOfElements == 1);
|
||||
ASSERT((sgList->Elements[0].Address.LowPart & 3) == 0);
|
||||
ASSERT(sgList->Elements[0].Length <= MAXIMUM_FRAME_SIZE);
|
||||
|
||||
if (Adapter->TxFull)
|
||||
{
|
||||
NDIS_DbgPrint(MIN_TRACE, ("All TX descriptors are full\n"));
|
||||
return NDIS_STATUS_RESOURCES;
|
||||
}
|
||||
|
||||
TransmitLength = sgList->Elements[0].Length;
|
||||
TransmitBuffer = sgList->Elements[0].Address;
|
||||
Adapter->TransmitPackets[Adapter->CurrentTxDesc] = Packet;
|
||||
|
||||
Status = NICTransmitPacket(Adapter, TransmitBuffer, TransmitLength);
|
||||
if (Status != NDIS_STATUS_SUCCESS)
|
||||
{
|
||||
NDIS_DbgPrint(MIN_TRACE, ("Transmit packet failed\n"));
|
||||
return Status;
|
||||
}
|
||||
|
||||
return NDIS_STATUS_PENDING;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MiniportHalt(
|
||||
|
@ -264,12 +226,7 @@ MiniportInitialize(
|
|||
|
||||
/* 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;
|
||||
}
|
||||
NICApplyInterruptMask(Adapter);
|
||||
|
||||
/* Turn on TX and RX now */
|
||||
Status = NICEnableTxRx(Adapter);
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
|
||||
typedef struct _E1000_ADAPTER
|
||||
{
|
||||
/* NIC Memory */
|
||||
volatile PUCHAR IoBase;
|
||||
NDIS_PHYSICAL_ADDRESS IoAddress;
|
||||
ULONG IoLength;
|
||||
|
||||
// NDIS_SPIN_LOCK AdapterLock;
|
||||
|
||||
NDIS_HANDLE AdapterHandle;
|
||||
|
@ -35,9 +40,11 @@ typedef struct _E1000_ADAPTER
|
|||
USHORT SubsystemVendorID;
|
||||
|
||||
UCHAR PermanentMacAddress[IEEE_802_ADDR_LENGTH];
|
||||
|
||||
struct {
|
||||
UCHAR MacAddress[IEEE_802_ADDR_LENGTH];
|
||||
} MulticastList[MAXIMUM_MULTICAST_ADDRESSES];
|
||||
ULONG MulticastListSize;
|
||||
|
||||
ULONG LinkSpeedMbps;
|
||||
ULONG MediaState;
|
||||
|
@ -48,11 +55,6 @@ typedef struct _E1000_ADAPTER
|
|||
ULONG IoPortLength;
|
||||
volatile PUCHAR IoPort;
|
||||
|
||||
/* NIC Memory */
|
||||
NDIS_PHYSICAL_ADDRESS IoAddress;
|
||||
ULONG IoLength;
|
||||
volatile PUCHAR IoBase;
|
||||
|
||||
/* Interrupt */
|
||||
ULONG InterruptVector;
|
||||
ULONG InterruptLevel;
|
||||
|
@ -63,7 +65,9 @@ typedef struct _E1000_ADAPTER
|
|||
BOOLEAN InterruptRegistered;
|
||||
|
||||
LONG InterruptMask;
|
||||
LONG InterruptPending;
|
||||
|
||||
_Interlocked_
|
||||
volatile LONG InterruptPending;
|
||||
|
||||
|
||||
/* Transmit */
|
||||
|
@ -156,22 +160,6 @@ NTAPI
|
|||
NICApplyPacketFilter(
|
||||
IN PE1000_ADAPTER Adapter);
|
||||
|
||||
NDIS_STATUS
|
||||
NTAPI
|
||||
NICApplyInterruptMask(
|
||||
IN PE1000_ADAPTER Adapter);
|
||||
|
||||
NDIS_STATUS
|
||||
NTAPI
|
||||
NICDisableInterrupts(
|
||||
IN PE1000_ADAPTER Adapter);
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
NICInterruptRecognized(
|
||||
IN PE1000_ADAPTER Adapter,
|
||||
OUT PBOOLEAN InterruptRecognized);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
NICUpdateLinkStatus(
|
||||
|
@ -179,10 +167,10 @@ NICUpdateLinkStatus(
|
|||
|
||||
NDIS_STATUS
|
||||
NTAPI
|
||||
NICTransmitPacket(
|
||||
IN PE1000_ADAPTER Adapter,
|
||||
IN PHYSICAL_ADDRESS PhysicalAddress,
|
||||
IN ULONG Length);
|
||||
MiniportSend(
|
||||
_In_ NDIS_HANDLE MiniportAdapterContext,
|
||||
_In_ PNDIS_PACKET Packet,
|
||||
_In_ UINT Flags);
|
||||
|
||||
NDIS_STATUS
|
||||
NTAPI
|
||||
|
@ -216,19 +204,54 @@ NTAPI
|
|||
MiniportHandleInterrupt(
|
||||
IN NDIS_HANDLE MiniportAdapterContext);
|
||||
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
NTAPI
|
||||
E1000ReadUlong(
|
||||
IN PE1000_ADAPTER Adapter,
|
||||
IN ULONG Address,
|
||||
OUT PULONG Value);
|
||||
_In_ PE1000_ADAPTER Adapter,
|
||||
_In_ ULONG Address,
|
||||
_Out_ PULONG Value)
|
||||
{
|
||||
NdisReadRegisterUlong((PULONG)(Adapter->IoBase + Address), Value);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
NTAPI
|
||||
E1000WriteUlong(
|
||||
IN PE1000_ADAPTER Adapter,
|
||||
IN ULONG Address,
|
||||
IN ULONG Value);
|
||||
_In_ PE1000_ADAPTER Adapter,
|
||||
_In_ ULONG Address,
|
||||
_In_ ULONG Value)
|
||||
{
|
||||
NdisWriteRegisterUlong((PULONG)(Adapter->IoBase + Address), Value);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
E1000WriteIoUlong(
|
||||
_In_ PE1000_ADAPTER Adapter,
|
||||
_In_ ULONG Address,
|
||||
_In_ ULONG Value)
|
||||
{
|
||||
volatile ULONG Dummy;
|
||||
|
||||
NdisRawWritePortUlong((PULONG)(Adapter->IoPort), Address);
|
||||
NdisReadRegisterUlong(Adapter->IoBase + E1000_REG_STATUS, &Dummy);
|
||||
NdisRawWritePortUlong((PULONG)(Adapter->IoPort + 4), Value);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
NICApplyInterruptMask(
|
||||
_In_ PE1000_ADAPTER Adapter)
|
||||
{
|
||||
E1000WriteUlong(Adapter, E1000_REG_IMS, Adapter->InterruptMask /*| 0x1F6DC*/);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
NICDisableInterrupts(
|
||||
_In_ PE1000_ADAPTER Adapter)
|
||||
{
|
||||
E1000WriteUlong(Adapter, E1000_REG_IMC, ~0);
|
||||
}
|
||||
|
||||
#endif /* _E1000_PCH_ */
|
||||
|
|
85
drivers/network/dd/e1000/send.c
Normal file
85
drivers/network/dd/e1000/send.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Intel PRO/1000 Driver
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later.html)
|
||||
* PURPOSE: Sending packets
|
||||
* COPYRIGHT: Copyright 2018 Mark Jansen <mark.jansen@reactos.org>
|
||||
* Copyright 2019 Victor Perevertkin <victor.perevertkin@reactos.org>
|
||||
*/
|
||||
|
||||
#include "nic.h"
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
static
|
||||
NDIS_STATUS
|
||||
NICTransmitPacket(
|
||||
_In_ PE1000_ADAPTER Adapter,
|
||||
_In_ PHYSICAL_ADDRESS PhysicalAddress,
|
||||
_In_ ULONG Length)
|
||||
{
|
||||
volatile PE1000_TRANSMIT_DESCRIPTOR TransmitDescriptor;
|
||||
|
||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
TransmitDescriptor = Adapter->TransmitDescriptors + Adapter->CurrentTxDesc;
|
||||
TransmitDescriptor->Address = PhysicalAddress.QuadPart;
|
||||
TransmitDescriptor->Length = Length;
|
||||
TransmitDescriptor->ChecksumOffset = 0;
|
||||
TransmitDescriptor->Command = E1000_TDESC_CMD_RS | E1000_TDESC_CMD_IFCS |
|
||||
E1000_TDESC_CMD_EOP | E1000_TDESC_CMD_IDE;
|
||||
TransmitDescriptor->Status = 0;
|
||||
TransmitDescriptor->ChecksumStartField = 0;
|
||||
TransmitDescriptor->Special = 0;
|
||||
|
||||
Adapter->CurrentTxDesc = (Adapter->CurrentTxDesc + 1) % NUM_TRANSMIT_DESCRIPTORS;
|
||||
|
||||
E1000WriteUlong(Adapter, E1000_REG_TDT, Adapter->CurrentTxDesc);
|
||||
|
||||
if (Adapter->CurrentTxDesc == Adapter->LastTxDesc)
|
||||
{
|
||||
NDIS_DbgPrint(MID_TRACE, ("All TX descriptors are full now\n"));
|
||||
Adapter->TxFull = TRUE;
|
||||
}
|
||||
|
||||
return NDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NDIS_STATUS
|
||||
NTAPI
|
||||
MiniportSend(
|
||||
_In_ NDIS_HANDLE MiniportAdapterContext,
|
||||
_In_ PNDIS_PACKET Packet,
|
||||
_In_ UINT Flags)
|
||||
{
|
||||
PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext;
|
||||
PSCATTER_GATHER_LIST sgList;
|
||||
ULONG TransmitLength;
|
||||
PHYSICAL_ADDRESS TransmitBuffer;
|
||||
NDIS_STATUS Status;
|
||||
|
||||
sgList = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, ScatterGatherListPacketInfo);
|
||||
|
||||
ASSERT(sgList != NULL);
|
||||
ASSERT(sgList->NumberOfElements == 1);
|
||||
ASSERT((sgList->Elements[0].Address.LowPart & 3) == 0);
|
||||
ASSERT(sgList->Elements[0].Length <= MAXIMUM_FRAME_SIZE);
|
||||
|
||||
if (Adapter->TxFull)
|
||||
{
|
||||
NDIS_DbgPrint(MIN_TRACE, ("All TX descriptors are full\n"));
|
||||
return NDIS_STATUS_RESOURCES;
|
||||
}
|
||||
|
||||
TransmitLength = sgList->Elements[0].Length;
|
||||
TransmitBuffer = sgList->Elements[0].Address;
|
||||
Adapter->TransmitPackets[Adapter->CurrentTxDesc] = Packet;
|
||||
|
||||
Status = NICTransmitPacket(Adapter, TransmitBuffer, TransmitLength);
|
||||
if (Status != NDIS_STATUS_SUCCESS)
|
||||
{
|
||||
NDIS_DbgPrint(MIN_TRACE, ("Transmit packet failed\n"));
|
||||
return Status;
|
||||
}
|
||||
|
||||
return NDIS_STATUS_PENDING;
|
||||
}
|
Loading…
Reference in a new issue