mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
- Fix receive to work on VMware emulated adapters. We need to set busmaster bit on PCI command register in order to get packets. Otherwise we just get "missing frame" error and the ring buffer remains empty.
- Indicate receive completition. - Implement basic packet transmitting. - Don't read slot number from registry and report itself as NDIS 5.0 miniport. - Fix nasty bugs in halt code path (incorrect assignment and wrong parameters to NdisMFreeSharedMemory calls). svn path=/trunk/; revision=11270
This commit is contained in:
parent
2dea5c279b
commit
f321359e16
6 changed files with 269 additions and 241 deletions
|
@ -3,10 +3,10 @@ TARGET_TYPE = driver
|
|||
TARGET_NAME = pcnet
|
||||
|
||||
#
|
||||
# - must define NDIS40 to get the right characteristics struct
|
||||
# - must define NDIS50 to get the right characteristics struct
|
||||
# - must define anonymous unions to make physical addresses work right
|
||||
#
|
||||
TARGET_CFLAGS = -I. -DDBG=1 -Wall -Werror -DNDIS40 -DANONYMOUSUNIONS
|
||||
TARGET_CFLAGS = -I. -DDBG=0 -Wall -Werror -DNDIS50 -DANONYMOUSUNIONS
|
||||
|
||||
TARGET_OBJECTS = pcnet.o requests.o
|
||||
TARGET_DDKLIBS = ndis.a
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* ReactOS AMD PCNet Driver
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
|
||||
*
|
||||
* Copyright (C) 2003 Vizzini <vizzini@plasmic.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -16,14 +17,14 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* PROJECT: ReactOS AMD PCNet Driver
|
||||
* FILE: pcnet/pci.h
|
||||
* PURPOSE: PCI configuration constants
|
||||
* PROGRAMMER: Vizzini (vizzini@plasmic.com)
|
||||
* PURPOSE:
|
||||
* PCI configuration constants
|
||||
* REVISIONS:
|
||||
* 1-Sept-2003 vizzini - Created
|
||||
* 01-Sept-2003 vizzini - Created
|
||||
*/
|
||||
|
||||
#ifndef _PCI_
|
||||
#define _PCI_
|
||||
|
||||
/* PCI Config Space Offset Definitions */
|
||||
#define PCI_PCIID 0x0 /* pci id - query 32 bits */
|
||||
|
@ -67,3 +68,4 @@
|
|||
#define PCI_SERR 0x2000 /* signalled error */
|
||||
#define PCI_PERR 0x4000 /* parity error */
|
||||
|
||||
#endif /* _PCI_ */
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/*
|
||||
* ReactOS AMD PCNet Driver
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
|
||||
*
|
||||
* Copyright (C) 2003 Vizzini <vizzini@plasmic.com>
|
||||
* Copyright (C) 2004 Filip Navara <navaraf@reactos.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -16,20 +18,21 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* PROJECT: ReactOS AMD PCNet Driver
|
||||
* FILE: drivers/net/dd/pcnet/pcnet.c
|
||||
* PURPOSE: PCNet Device Driver
|
||||
* PROGRAMMER: Vizzini (vizzini@plasmic.com)
|
||||
* REVISIONS:
|
||||
* 9-Sept-2003 vizzini - Created
|
||||
* 09-Sep-2003 vizzini - Created
|
||||
* 10-Oct-2004 navaraf - Fix receive to work on VMware adapters (
|
||||
* need to set busmaster bit on PCI).
|
||||
* - Indicate receive completition.
|
||||
* - Implement packet transmitting.
|
||||
* - Don't read slot number from registry and
|
||||
* report itself as NDIS 5.0 miniport.
|
||||
* 11-Oct-2004 navaraf - Fix nasty bugs in halt code path.
|
||||
*
|
||||
* NOTES:
|
||||
* - this is hard-coded to NDIS4
|
||||
* - this assumes a little-endian machine
|
||||
* - this is hard-coded to NDIS5
|
||||
* - this assumes a 32-bit machine
|
||||
* - this doesn't handle multiple PCNET NICs yet
|
||||
* - this driver includes both NdisRaw and NdisImmediate calls
|
||||
* for NDIS testing purposes. Pick your poison below.
|
||||
*/
|
||||
|
||||
#include <ndis.h>
|
||||
#include "pci.h"
|
||||
#include "pcnethw.h"
|
||||
|
@ -49,10 +52,12 @@ MiniportHandleInterrupt(
|
|||
{
|
||||
PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
|
||||
USHORT Data;
|
||||
BOOLEAN ErrorHandled = FALSE;
|
||||
#if DBG
|
||||
BOOLEAN ReceiveHandled = FALSE;
|
||||
BOOLEAN ErrorHandled = FALSE;
|
||||
BOOLEAN IdonHandled = FALSE;
|
||||
USHORT Temp;
|
||||
BOOLEAN TransmitHandled = FALSE;
|
||||
#endif
|
||||
|
||||
PCNET_DbgPrint(("Called\n"));
|
||||
|
||||
|
@ -63,6 +68,9 @@ MiniportHandleInterrupt(
|
|||
|
||||
while(Data & CSR0_INTR)
|
||||
{
|
||||
/* Clear interrupt flags early to avoid race conditions. */
|
||||
NdisRawWritePortUshort(Adapter->PortOffset + RDP, Data);
|
||||
|
||||
if(Data & CSR0_ERR)
|
||||
{
|
||||
#if DBG
|
||||
|
@ -75,10 +83,7 @@ MiniportHandleInterrupt(
|
|||
ErrorHandled = TRUE;
|
||||
#endif
|
||||
|
||||
PCNET_DbgPrint(("clearing an error\n"));
|
||||
NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_MERR|CSR0_BABL|CSR0_CERR|CSR0_MISS);
|
||||
NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Temp);
|
||||
PCNET_DbgPrint(("CSR0 is now 0x%x\n", Temp));
|
||||
PCNET_DbgPrint(("error: %x\n", Data & (CSR0_MERR|CSR0_BABL|CSR0_CERR|CSR0_MISS)));
|
||||
}
|
||||
else if(Data & CSR0_IDON)
|
||||
{
|
||||
|
@ -92,10 +97,7 @@ MiniportHandleInterrupt(
|
|||
IdonHandled = TRUE;
|
||||
#endif
|
||||
|
||||
PCNET_DbgPrint(("clearing IDON\n"));
|
||||
NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_IDON);
|
||||
NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Temp);
|
||||
PCNET_DbgPrint(("CSR0 is now 0x%x\n", Temp));
|
||||
PCNET_DbgPrint(("IDON\n"));
|
||||
}
|
||||
else if(Data & CSR0_RINT)
|
||||
{
|
||||
|
@ -109,10 +111,7 @@ MiniportHandleInterrupt(
|
|||
ReceiveHandled = TRUE;
|
||||
#endif
|
||||
|
||||
PCNET_DbgPrint(("receive interrupt - clearing\n"));
|
||||
NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_RINT);
|
||||
NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Temp);
|
||||
PCNET_DbgPrint(("CSR0 is now 0x%x\n", Temp));
|
||||
PCNET_DbgPrint(("receive interrupt\n"));
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
@ -144,19 +143,60 @@ MiniportHandleInterrupt(
|
|||
PCNET_DbgPrint(("Indicating a %d-byte packet (index %d)\n", ByteCount, Adapter->CurrentReceiveDescriptorIndex));
|
||||
|
||||
NdisMEthIndicateReceive(Adapter->MiniportAdapterHandle, 0, Buffer, 14, Buffer+14, ByteCount-14, ByteCount-14);
|
||||
NdisMEthIndicateReceiveComplete(Adapter->MiniportAdapterHandle);
|
||||
|
||||
memset(Descriptor, 0, sizeof(RECEIVE_DESCRIPTOR));
|
||||
RtlZeroMemory(Descriptor, sizeof(RECEIVE_DESCRIPTOR));
|
||||
Descriptor->RBADR =
|
||||
(ULONG)(Adapter->ReceiveBufferPtrPhys + Adapter->CurrentReceiveDescriptorIndex * BUFFER_SIZE);
|
||||
Descriptor->BCNT = (-BUFFER_SIZE) | 0xf000;
|
||||
Descriptor->FLAGS &= RD_OWN;
|
||||
Descriptor->FLAGS |= RD_OWN;
|
||||
|
||||
Adapter->CurrentReceiveDescriptorIndex++;
|
||||
|
||||
if(Adapter->CurrentReceiveDescriptorIndex == NUMBER_OF_BUFFERS)
|
||||
Adapter->CurrentReceiveDescriptorIndex = 0;
|
||||
Adapter->CurrentReceiveDescriptorIndex %= NUMBER_OF_BUFFERS;
|
||||
}
|
||||
}
|
||||
else if(Data & CSR0_TINT)
|
||||
{
|
||||
PTRANSMIT_DESCRIPTOR Descriptor;
|
||||
|
||||
#if DBG
|
||||
if(TransmitHandled)
|
||||
{
|
||||
PCNET_DbgPrint(("TRANSMIT HANDLED TWO TIMES\n"));
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
TransmitHandled = TRUE;
|
||||
#endif
|
||||
|
||||
PCNET_DbgPrint(("transmit interrupt\n"));
|
||||
|
||||
while (Adapter->CurrentTransmitStartIndex !=
|
||||
Adapter->CurrentTransmitEndIndex)
|
||||
{
|
||||
Descriptor = Adapter->TransmitDescriptorRingVirt + Adapter->CurrentTransmitStartIndex;
|
||||
|
||||
PCNET_DbgPrint(("buffer %d flags %x flags2 %x\n",
|
||||
Adapter->CurrentTransmitStartIndex,
|
||||
Descriptor->FLAGS, Descriptor->FLAGS2));
|
||||
|
||||
if (Descriptor->FLAGS & TD1_OWN)
|
||||
{
|
||||
PCNET_DbgPrint(("non-TXed buffer\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
if (Descriptor->FLAGS & TD1_ERR)
|
||||
{
|
||||
PCNET_DbgPrint(("major error: %x\n", Descriptor->FLAGS2));
|
||||
break;
|
||||
}
|
||||
|
||||
Adapter->CurrentTransmitStartIndex++;
|
||||
Adapter->CurrentTransmitStartIndex %= NUMBER_OF_BUFFERS;
|
||||
}
|
||||
NdisMSendResourcesAvailable(Adapter->MiniportAdapterHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
PCNET_DbgPrint(("UNHANDLED INTERRUPT\n"));
|
||||
|
@ -191,7 +231,7 @@ MiQueryCard(
|
|||
NDIS_STATUS Status;
|
||||
|
||||
/* Detect the card in the configured slot */
|
||||
Status = NdisReadPciSlotInformation(Adapter->MiniportAdapterHandle, Adapter->SlotNumber, PCI_PCIID, &buf32, 4);
|
||||
Status = NdisReadPciSlotInformation(Adapter->MiniportAdapterHandle, 0, PCI_PCIID, &buf32, 4);
|
||||
if(Status != 4)
|
||||
{
|
||||
Status = NDIS_STATUS_FAILURE;
|
||||
|
@ -203,36 +243,18 @@ MiQueryCard(
|
|||
if(buf32 != PCI_ID)
|
||||
{
|
||||
Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
|
||||
PCNET_DbgPrint(("card in slot 0x%x isn't us: 0x%x\n", Adapter->SlotNumber, buf32));
|
||||
PCNET_DbgPrint(("card in slot isn't our: 0x%x\n", 0, buf32));
|
||||
BREAKPOINT;
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = NdisReadPciSlotInformation(Adapter->MiniportAdapterHandle, Adapter->SlotNumber,
|
||||
PCI_COMMAND, &buf32, 4);
|
||||
if(Status != 4)
|
||||
{
|
||||
PCNET_DbgPrint(("NdisReadPciSlotInformation failed\n"));
|
||||
BREAKPOINT;
|
||||
return NDIS_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
PCNET_DbgPrint(("config/status register: 0x%x\n", buf32));
|
||||
|
||||
if(buf32 & 0x1)
|
||||
{
|
||||
PCNET_DbgPrint(("io space access is enabled.\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
PCNET_DbgPrint(("io space is NOT enabled!\n"));
|
||||
BREAKPOINT;
|
||||
return NDIS_STATUS_FAILURE;
|
||||
}
|
||||
/* set busmaster and io space enable bits */
|
||||
buf32 = PCI_BMEN | PCI_IOEN;
|
||||
NdisWritePciSlotInformation(Adapter->MiniportAdapterHandle, 0, PCI_COMMAND, &buf32, 4);
|
||||
|
||||
/* get IO base physical address */
|
||||
buf32 = 0;
|
||||
Status = NdisReadPciSlotInformation(Adapter->MiniportAdapterHandle, Adapter->SlotNumber, PCI_IOBAR, &buf32, 4);
|
||||
Status = NdisReadPciSlotInformation(Adapter->MiniportAdapterHandle, 0, PCI_IOBAR, &buf32, 4);
|
||||
if(Status != 4)
|
||||
{
|
||||
Status = NDIS_STATUS_FAILURE;
|
||||
|
@ -253,7 +275,7 @@ MiQueryCard(
|
|||
Adapter->IoBaseAddress = buf32;
|
||||
|
||||
/* get interrupt vector */
|
||||
Status = NdisReadPciSlotInformation(Adapter->MiniportAdapterHandle, Adapter->SlotNumber, PCI_ILR, &buf8, 1);
|
||||
Status = NdisReadPciSlotInformation(Adapter->MiniportAdapterHandle, 0, PCI_ILR, &buf8, 1);
|
||||
if(Status != 1)
|
||||
{
|
||||
Status = NDIS_STATUS_FAILURE;
|
||||
|
@ -268,48 +290,6 @@ MiQueryCard(
|
|||
return NDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NDIS_STATUS
|
||||
MiGetConfig(
|
||||
PADAPTER Adapter,
|
||||
NDIS_HANDLE WrapperConfigurationContext)
|
||||
/*
|
||||
* FUNCTION: Get configuration parameters from the registry
|
||||
* ARGUMENTS:
|
||||
* Adapter: pointer to the Adapter struct for this NIC
|
||||
* WrapperConfigurationContext: Context passed into MiniportInitialize
|
||||
* RETURNS:
|
||||
* NDIS_STATUS_SUCCESS on success
|
||||
* NDIS_STATUS_{something} on failure (return val from other Ndis calls)
|
||||
*/
|
||||
{
|
||||
PNDIS_CONFIGURATION_PARAMETER Parameter;
|
||||
NDIS_HANDLE ConfigurationHandle = 0;
|
||||
UNICODE_STRING Keyword;
|
||||
NDIS_STATUS Status;
|
||||
|
||||
NdisOpenConfiguration(&Status, &ConfigurationHandle, WrapperConfigurationContext);
|
||||
if(Status != NDIS_STATUS_SUCCESS)
|
||||
{
|
||||
PCNET_DbgPrint(("Unable to open configuration: 0x%x\n", Status));
|
||||
BREAKPOINT;
|
||||
return Status;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&Keyword, L"SlotNumber");
|
||||
NdisReadConfiguration(&Status, &Parameter, ConfigurationHandle, &Keyword, NdisParameterInteger);
|
||||
if(Status != NDIS_STATUS_SUCCESS)
|
||||
{
|
||||
PCNET_DbgPrint(("Unable to read slot number: 0x%x\n", Status));
|
||||
BREAKPOINT;
|
||||
}
|
||||
else
|
||||
Adapter->SlotNumber = Parameter->ParameterData.IntegerData;
|
||||
|
||||
NdisCloseConfiguration(ConfigurationHandle);
|
||||
|
||||
return NDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NDIS_STATUS
|
||||
MiAllocateSharedMemory(
|
||||
PADAPTER Adapter)
|
||||
|
@ -346,7 +326,6 @@ MiAllocateSharedMemory(
|
|||
}
|
||||
|
||||
Adapter->InitializationBlockPhys = (PINITIALIZATION_BLOCK)NdisGetPhysicalAddressLow(PhysicalAddress);
|
||||
memset(Adapter->InitializationBlockVirt, 0, sizeof(INITIALIZATION_BLOCK));
|
||||
|
||||
/* allocate the transport descriptor ring */
|
||||
Adapter->TransmitDescriptorRingLength = sizeof(TRANSMIT_DESCRIPTOR) * NUMBER_OF_BUFFERS;
|
||||
|
@ -367,7 +346,7 @@ MiAllocateSharedMemory(
|
|||
}
|
||||
|
||||
Adapter->TransmitDescriptorRingPhys = (PTRANSMIT_DESCRIPTOR)NdisGetPhysicalAddressLow(PhysicalAddress);
|
||||
memset(Adapter->TransmitDescriptorRingVirt, 0, sizeof(TRANSMIT_DESCRIPTOR) * NUMBER_OF_BUFFERS);
|
||||
RtlZeroMemory(Adapter->TransmitDescriptorRingVirt, sizeof(TRANSMIT_DESCRIPTOR) * NUMBER_OF_BUFFERS);
|
||||
|
||||
/* allocate the receive descriptor ring */
|
||||
Adapter->ReceiveDescriptorRingLength = sizeof(RECEIVE_DESCRIPTOR) * NUMBER_OF_BUFFERS;
|
||||
|
@ -388,7 +367,7 @@ MiAllocateSharedMemory(
|
|||
}
|
||||
|
||||
Adapter->ReceiveDescriptorRingPhys = (PRECEIVE_DESCRIPTOR)NdisGetPhysicalAddressLow(PhysicalAddress);
|
||||
memset(Adapter->ReceiveDescriptorRingVirt, 0, sizeof(RECEIVE_DESCRIPTOR) * NUMBER_OF_BUFFERS);
|
||||
RtlZeroMemory(Adapter->ReceiveDescriptorRingVirt, sizeof(RECEIVE_DESCRIPTOR) * NUMBER_OF_BUFFERS);
|
||||
|
||||
/* allocate transmit buffers */
|
||||
Adapter->TransmitBufferLength = BUFFER_SIZE * NUMBER_OF_BUFFERS;
|
||||
|
@ -409,7 +388,7 @@ MiAllocateSharedMemory(
|
|||
}
|
||||
|
||||
Adapter->TransmitBufferPtrPhys = (PCHAR)NdisGetPhysicalAddressLow(PhysicalAddress);
|
||||
memset(Adapter->TransmitBufferPtrVirt, 0, BUFFER_SIZE * NUMBER_OF_BUFFERS);
|
||||
RtlZeroMemory(Adapter->TransmitBufferPtrVirt, BUFFER_SIZE * NUMBER_OF_BUFFERS);
|
||||
|
||||
/* allocate receive buffers */
|
||||
Adapter->ReceiveBufferLength = BUFFER_SIZE * NUMBER_OF_BUFFERS;
|
||||
|
@ -430,7 +409,7 @@ MiAllocateSharedMemory(
|
|||
}
|
||||
|
||||
Adapter->ReceiveBufferPtrPhys = (PCHAR)NdisGetPhysicalAddressLow(PhysicalAddress);
|
||||
memset(Adapter->ReceiveBufferPtrVirt, 0, BUFFER_SIZE * NUMBER_OF_BUFFERS);
|
||||
RtlZeroMemory(Adapter->ReceiveBufferPtrVirt, BUFFER_SIZE * NUMBER_OF_BUFFERS);
|
||||
|
||||
/* initialize tx descriptors */
|
||||
TransmitDescriptor = Adapter->TransmitDescriptorRingVirt;
|
||||
|
@ -448,8 +427,8 @@ MiAllocateSharedMemory(
|
|||
for(i = 0; i < NUMBER_OF_BUFFERS; i++)
|
||||
{
|
||||
(ReceiveDescriptor+i)->RBADR = (ULONG)Adapter->ReceiveBufferPtrPhys + i * BUFFER_SIZE;
|
||||
(ReceiveDescriptor+i)->BCNT = 0xf0000 | -BUFFER_SIZE; /* 2's compliment + set top 4 bits */
|
||||
(ReceiveDescriptor+i)->FLAGS |= RD_OWN;
|
||||
(ReceiveDescriptor+i)->BCNT = 0xf000 | -BUFFER_SIZE; /* 2's compliment + set top 4 bits */
|
||||
(ReceiveDescriptor+i)->FLAGS = RD_OWN;
|
||||
}
|
||||
|
||||
PCNET_DbgPrint(("receive ring initialized\n"));
|
||||
|
@ -468,9 +447,18 @@ MiPrepareInitializationBlock(
|
|||
{
|
||||
ULONG i = 0;
|
||||
|
||||
RtlZeroMemory(Adapter->InitializationBlockVirt, sizeof(INITIALIZATION_BLOCK));
|
||||
|
||||
/* read burned-in address from card */
|
||||
for(i = 0; i < 6; i++)
|
||||
NdisRawReadPortUchar(Adapter->PortOffset + i, Adapter->InitializationBlockVirt->PADR + i);
|
||||
PCNET_DbgPrint(("MAC address: %02x-%02x-%02x-%02x-%02x-%02x\n",
|
||||
Adapter->InitializationBlockVirt->PADR[0],
|
||||
Adapter->InitializationBlockVirt->PADR[1],
|
||||
Adapter->InitializationBlockVirt->PADR[2],
|
||||
Adapter->InitializationBlockVirt->PADR[3],
|
||||
Adapter->InitializationBlockVirt->PADR[4],
|
||||
Adapter->InitializationBlockVirt->PADR[5]));
|
||||
|
||||
/* set up receive ring */
|
||||
PCNET_DbgPrint(("Receive ring physical address: 0x%x\n", Adapter->ReceiveDescriptorRingPhys));
|
||||
|
@ -500,35 +488,35 @@ MiFreeSharedMemory(
|
|||
{
|
||||
PhysicalAddress.u.LowPart = (ULONG)Adapter->InitializationBlockPhys;
|
||||
NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->InitializationBlockLength,
|
||||
FALSE, (PVOID *)&Adapter->InitializationBlockVirt, PhysicalAddress);
|
||||
FALSE, Adapter->InitializationBlockVirt, PhysicalAddress);
|
||||
}
|
||||
|
||||
if(Adapter->TransmitDescriptorRingVirt)
|
||||
{
|
||||
PhysicalAddress.u.LowPart = (ULONG)Adapter->TransmitDescriptorRingPhys;
|
||||
NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->TransmitDescriptorRingLength,
|
||||
FALSE, (PVOID *)&Adapter->TransmitDescriptorRingVirt, PhysicalAddress);
|
||||
FALSE, Adapter->TransmitDescriptorRingVirt, PhysicalAddress);
|
||||
}
|
||||
|
||||
if(Adapter->ReceiveDescriptorRingVirt)
|
||||
{
|
||||
PhysicalAddress.u.LowPart = (ULONG)Adapter->ReceiveDescriptorRingPhys;
|
||||
NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->ReceiveDescriptorRingLength,
|
||||
FALSE, (PVOID *)&Adapter->ReceiveDescriptorRingVirt, PhysicalAddress);
|
||||
FALSE, Adapter->ReceiveDescriptorRingVirt, PhysicalAddress);
|
||||
}
|
||||
|
||||
if(Adapter->TransmitBufferPtrVirt)
|
||||
{
|
||||
PhysicalAddress.u.LowPart = (ULONG)Adapter->TransmitBufferPtrPhys;
|
||||
NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->TransmitBufferLength,
|
||||
FALSE, (PVOID *)&Adapter->TransmitBufferPtrVirt, PhysicalAddress);
|
||||
FALSE, Adapter->TransmitBufferPtrVirt, PhysicalAddress);
|
||||
}
|
||||
|
||||
if(Adapter->ReceiveBufferPtrVirt)
|
||||
{
|
||||
PhysicalAddress.u.LowPart = (ULONG)Adapter->ReceiveBufferPtrPhys;
|
||||
NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->ReceiveBufferLength,
|
||||
FALSE, (PVOID *)&Adapter->ReceiveBufferPtrVirt, PhysicalAddress);
|
||||
FALSE, Adapter->ReceiveBufferPtrVirt, PhysicalAddress);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -544,7 +532,7 @@ MiniportHalt(
|
|||
* - Called by NDIS at PASSIVE_LEVEL
|
||||
*/
|
||||
{
|
||||
PADAPTER Adapter = (PADAPTER)Adapter;
|
||||
PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
|
||||
|
||||
PCNET_DbgPrint(("Called\n"));
|
||||
ASSERT(Adapter);
|
||||
|
@ -765,7 +753,7 @@ MiniportInitialize(
|
|||
return Status;
|
||||
}
|
||||
|
||||
memset(Adapter,0,sizeof(ADAPTER));
|
||||
RtlZeroMemory(Adapter, sizeof(ADAPTER));
|
||||
|
||||
Adapter->MiniportAdapterHandle = MiniportAdapterHandle;
|
||||
|
||||
|
@ -774,16 +762,6 @@ MiniportInitialize(
|
|||
|
||||
do
|
||||
{
|
||||
/* get registry config */
|
||||
Status = MiGetConfig(Adapter, WrapperConfigurationContext);
|
||||
if(Status != NDIS_STATUS_SUCCESS)
|
||||
{
|
||||
PCNET_DbgPrint(("MiGetConfig failed\n"));
|
||||
Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
|
||||
BREAKPOINT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Card-specific detection and setup */
|
||||
Status = MiQueryCard(Adapter);
|
||||
if(Status != NDIS_STATUS_SUCCESS)
|
||||
|
@ -815,7 +793,7 @@ MiniportInitialize(
|
|||
}
|
||||
|
||||
/* set up the interrupt */
|
||||
memset(&Adapter->InterruptObject, 0, sizeof(NDIS_MINIPORT_INTERRUPT));
|
||||
RtlZeroMemory(&Adapter->InterruptObject, sizeof(NDIS_MINIPORT_INTERRUPT));
|
||||
Status = NdisMRegisterInterrupt(&Adapter->InterruptObject, Adapter->MiniportAdapterHandle, Adapter->InterruptVector,
|
||||
Adapter->InterruptVector, FALSE, TRUE, NdisInterruptLevelSensitive);
|
||||
if(Status != NDIS_STATUS_SUCCESS)
|
||||
|
@ -967,12 +945,75 @@ MiniportSend(
|
|||
* Packet: The NDIS_PACKET to be sent
|
||||
* Flags: Flags associated with Packet
|
||||
* RETURNS:
|
||||
* NDIS_STATUS_SUCCESS on all requests
|
||||
* NDIS_STATUS_SUCCESS on processed requests
|
||||
* NDIS_STATUS_RESOURCES if there's no place in buffer ring
|
||||
* NOTES:
|
||||
* - Called by NDIS at DISPATCH_LEVEL
|
||||
*/
|
||||
{
|
||||
PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
|
||||
PTRANSMIT_DESCRIPTOR Desc;
|
||||
PNDIS_BUFFER NdisBuffer;
|
||||
PVOID SourceBuffer;
|
||||
UINT TotalPacketLength, SourceLength, Position = 0;
|
||||
|
||||
PCNET_DbgPrint(("Called\n"));
|
||||
|
||||
/* Check if we have free entry in our circular buffer. */
|
||||
if ((Adapter->CurrentTransmitEndIndex + 1 ==
|
||||
Adapter->CurrentTransmitStartIndex) ||
|
||||
(Adapter->CurrentTransmitEndIndex == NUMBER_OF_BUFFERS - 1 &&
|
||||
Adapter->CurrentTransmitStartIndex == 0))
|
||||
{
|
||||
PCNET_DbgPrint(("No free space in circular buffer\n"));
|
||||
return NDIS_STATUS_RESOURCES;
|
||||
}
|
||||
|
||||
Desc = Adapter->TransmitDescriptorRingVirt + Adapter->CurrentTransmitEndIndex;
|
||||
|
||||
NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, &TotalPacketLength);
|
||||
ASSERT(TotalPacketLength <= BUFFER_SIZE);
|
||||
|
||||
PCNET_DbgPrint(("TotalPacketLength: %x\n", TotalPacketLength));
|
||||
|
||||
while (NdisBuffer)
|
||||
{
|
||||
NdisQueryBuffer(NdisBuffer, &SourceBuffer, &SourceLength);
|
||||
|
||||
PCNET_DbgPrint(("Buffer: %x Length: %x\n", SourceBuffer, SourceLength));
|
||||
|
||||
RtlCopyMemory(Adapter->TransmitBufferPtrVirt +
|
||||
Adapter->CurrentTransmitEndIndex * BUFFER_SIZE + Position,
|
||||
SourceBuffer, SourceLength);
|
||||
|
||||
Position += SourceLength;
|
||||
|
||||
NdisGetNextBuffer(NdisBuffer, &NdisBuffer);
|
||||
}
|
||||
|
||||
#if DBG
|
||||
{
|
||||
PUCHAR Ptr = Adapter->TransmitBufferPtrVirt +
|
||||
Adapter->CurrentTransmitEndIndex * BUFFER_SIZE;
|
||||
for (Position = 0; Position < TotalPacketLength; Position++)
|
||||
{
|
||||
if (Position % 16 == 0)
|
||||
DbgPrint("\n");
|
||||
DbgPrint("%x ", *Ptr++);
|
||||
}
|
||||
}
|
||||
DbgPrint("\n");
|
||||
#endif
|
||||
|
||||
Adapter->CurrentTransmitEndIndex++;
|
||||
Adapter->CurrentTransmitEndIndex %= NUMBER_OF_BUFFERS;
|
||||
|
||||
Desc->FLAGS = TD1_OWN | TD1_STP | TD1_ENP;
|
||||
Desc->BCNT = 0xf000 | -TotalPacketLength;
|
||||
|
||||
NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
|
||||
NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_IENA | CSR0_TDMD);
|
||||
|
||||
return NDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -998,8 +1039,9 @@ DriverEntry(
|
|||
NDIS_MINIPORT_CHARACTERISTICS Characteristics;
|
||||
NDIS_STATUS Status;
|
||||
|
||||
memset(&Characteristics, 0, sizeof(Characteristics));
|
||||
Characteristics.MajorNdisVersion = 4;
|
||||
RtlZeroMemory(&Characteristics, sizeof(Characteristics));
|
||||
Characteristics.MajorNdisVersion = 5;
|
||||
Characteristics.MinorNdisVersion = 0;
|
||||
Characteristics.HaltHandler = MiniportHalt;
|
||||
Characteristics.HandleInterruptHandler = MiniportHandleInterrupt;
|
||||
Characteristics.InitializeHandler = MiniportInitialize;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/*
|
||||
* ReactOS AMD PCNet Driver
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
|
||||
*
|
||||
* Copyright (C) 2003 Vizzini <vizzini@plasmic.com>
|
||||
* Copyright (C) 2004 Filip Navara <navaraf@reactos.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -16,15 +18,9 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* PROJECT: ReactOS AMD PCNet Driver
|
||||
* FILE: pcnet/pcnet.h
|
||||
* PURPOSE: PCNet Device Driver
|
||||
* PROGRAMMER: Vizzini (vizzini@plasmic.com)
|
||||
* REVISIONS:
|
||||
* 1-Sept-2003 vizzini - Created
|
||||
* 01-Sep-2003 vizzini - Created
|
||||
* NOTES:
|
||||
* - this is hard-coded to NDIS4
|
||||
* - this assumes a little-endian machine
|
||||
* - this assumes a 32-bit machine, where sizeof(PVOID) = 32 and sizeof(USHORT) = 16
|
||||
* - this assumes 32-bit physical addresses
|
||||
*/
|
||||
|
@ -37,8 +33,6 @@ typedef struct _ADAPTER
|
|||
{
|
||||
NDIS_HANDLE MiniportAdapterHandle;
|
||||
ULONG Flags;
|
||||
ULONG BusNumber;
|
||||
ULONG SlotNumber;
|
||||
ULONG InterruptVector;
|
||||
ULONG IoBaseAddress;
|
||||
PVOID PortOffset;
|
||||
|
@ -47,6 +41,10 @@ typedef struct _ADAPTER
|
|||
ULONG CurrentPacketFilter;
|
||||
ULONG CurrentLookaheadSize;
|
||||
|
||||
/* circular indexes to transmit descriptors */
|
||||
ULONG CurrentTransmitStartIndex;
|
||||
ULONG CurrentTransmitEndIndex;
|
||||
|
||||
/* initialization block */
|
||||
ULONG InitializationBlockLength;
|
||||
PINITIALIZATION_BLOCK InitializationBlockVirt;
|
||||
|
@ -71,7 +69,6 @@ typedef struct _ADAPTER
|
|||
ULONG ReceiveBufferLength;
|
||||
PCHAR ReceiveBufferPtrVirt;
|
||||
PCHAR ReceiveBufferPtrPhys;
|
||||
|
||||
} ADAPTER, *PADAPTER;
|
||||
|
||||
/* forward declarations */
|
||||
|
@ -123,15 +120,5 @@ MiniportSetInformation(
|
|||
/* memory pool tag */
|
||||
#define PCNET_TAG 0xbaadf00d
|
||||
|
||||
/* stack validation */
|
||||
#define STACKENTER __asm__("movl %%esp, %0\n" : "=m" (esp));
|
||||
|
||||
#define STACKLEAVE {\
|
||||
unsigned long esptemp = esp; \
|
||||
__asm__ ("movl %%esp, %0\n": "=m" (esp)); \
|
||||
if(esp != esptemp) \
|
||||
__asm__ ("int $3\n"); \
|
||||
}
|
||||
|
||||
#endif // _PCNET_H_
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* ReactOS AMD PCNet Driver
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
|
||||
*
|
||||
* Copyright (C) 2003 Vizzini <vizzini@plasmic.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -16,17 +17,18 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* PROJECT: ReactOS AMD PCNet Driver
|
||||
* FILE: drivers/net/dd/pcnet/pcnethw.h
|
||||
* PURPOSE: PCNet hardware configuration constants
|
||||
* PROGRAMMER: Vizzini (vizzini@plasmic.com)
|
||||
* PURPOSE:
|
||||
* PCNet hardware configuration constants
|
||||
* REVISIONS:
|
||||
* 1-Sept-2003 vizzini - Created
|
||||
* 01-Sept-2003 vizzini - Created
|
||||
* NOTES:
|
||||
* - This file represents a clean re-implementation from the AMD
|
||||
* PCNet II chip documentation (Am79C790A, pub# 19436).
|
||||
*/
|
||||
|
||||
#ifndef _PCNETHW_
|
||||
#define _PCNETHW_
|
||||
|
||||
/* when in 32-bit mode, most registers require the top 16 bits be 0. */
|
||||
#define MASK16(__x__) ((__x__) & 0x0000ffff)
|
||||
|
||||
|
@ -408,4 +410,4 @@ typedef struct _TRANSMIT_DESCRIPTOR
|
|||
#define TD2_UFLO 0x4000 /* buffer underflow */
|
||||
#define TD2_BUFF 0x8000 /* buffer error */
|
||||
|
||||
|
||||
#endif /* _PCNETHW_ */
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
/*
|
||||
* ReactOS AMD PCNet Driver
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
|
||||
*
|
||||
* Copyright (C) 2000 Casper Hornstroup <chorns@users.sourceforge.net>
|
||||
* Copyright (C) 2003 Vizzini <vizzini@plasmic.com>
|
||||
* Copyright (C) 2004 Filip Navara <navaraf@reactos.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -16,16 +19,14 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* PROJECT: ReactOS AMD PCNet Driver
|
||||
* FILE: drivers/net/dd/pcnet/pcnet.c
|
||||
* PURPOSE: PCNet Device Driver
|
||||
* PROGRAMMERS: Vizzini (vizzini@plasmic.com),
|
||||
* PROGRAMMERS:
|
||||
* Vizzini (vizzini@plasmic.com),
|
||||
* borrowed very heavily from the ReactOS ne2000 driver by
|
||||
* Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* 14-Sept-2003 vizzini - Created
|
||||
* NOTES:
|
||||
*/
|
||||
|
||||
#include <ndis.h>
|
||||
#include "pcnethw.h"
|
||||
#include "pcnet.h"
|
||||
|
@ -124,12 +125,13 @@ MiniportQueryInformation(
|
|||
case OID_GEN_MEDIA_SUPPORTED:
|
||||
case OID_GEN_MEDIA_IN_USE:
|
||||
{
|
||||
NDIS_MEDIUM Medium = NdisMedium802_3;
|
||||
static const NDIS_MEDIUM Medium = NdisMedium802_3;
|
||||
CopyFrom = (PVOID)&Medium;
|
||||
CopySize = sizeof(NDIS_MEDIUM);
|
||||
break;
|
||||
}
|
||||
|
||||
case OID_GEN_CURRENT_LOOKAHEAD:
|
||||
case OID_GEN_MAXIMUM_LOOKAHEAD:
|
||||
{
|
||||
GenericULONG = 1500;
|
||||
|
@ -202,13 +204,6 @@ MiniportQueryInformation(
|
|||
break;
|
||||
}
|
||||
|
||||
case OID_GEN_CURRENT_LOOKAHEAD:
|
||||
{
|
||||
/* XXX make me a constant */
|
||||
GenericULONG = 1500;
|
||||
break;
|
||||
}
|
||||
|
||||
case OID_GEN_DRIVER_VERSION:
|
||||
{
|
||||
GenericULONG = 1;
|
||||
|
@ -294,7 +289,7 @@ MiniportQueryInformation(
|
|||
{
|
||||
*BytesNeeded = (CopySize - InformationBufferLength);
|
||||
*BytesWritten = 0;
|
||||
Status = NDIS_STATUS_INVALID_LENGTH;
|
||||
Status = NDIS_STATUS_BUFFER_TOO_SHORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue