Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518/* * ReactOS AMD PCNet Driver * * Copyright (C) 2000 Casper Hornstrup <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 * 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. * * PROGRAMMERS: * Vizzini (vizzini@plasmic.com), * borrowed very heavily from the ReactOS ne2000 driver by * Casper S. Hornstrup (chorns@users.sourceforge.net) * REVISIONS: * 14-Sep-2003 vizzini - Created * 17-Oct-2004 navaraf - Add multicast support. * - Add media state detection support. * - Protect the adapter context with spinlock * and move code talking to card to inside * NdisMSynchronizeWithInterrupt calls where * necessary. */
#include "pcnet.h"
#define NDEBUG#include <debug.h>
/* List of supported OIDs */static ULONG MiniportOIDList[] ={ 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_TRANSMIT_BLOCK_SIZE, OID_GEN_RECEIVE_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, OID_GEN_PHYSICAL_MEDIUM};
NDIS_STATUSNTAPIMiniportQueryInformation( IN NDIS_HANDLE MiniportAdapterContext, IN NDIS_OID Oid, IN PVOID InformationBuffer, IN ULONG InformationBufferLength, OUT PULONG BytesWritten, OUT PULONG BytesNeeded)/* * FUNCTION: Query an OID from the driver * ARGUMENTS: * MiniportAdapterContext: context originally passed to NdisMSetAttributes * Oid: OID NDIS is querying * InformationBuffer: pointer to buffer into which to write the results of the query * InformationBufferLength: size in bytes of InformationBuffer * BytesWritten: number of bytes written into InformationBuffer in response to the query * BytesNeeded: number of bytes needed to answer the query * RETURNS: * NDIS_STATUS_SUCCESS on all queries * NOTES: * - Called by NDIS at DISPATCH_LEVEL * - If InformationBufferLength is insufficient to store the results, return the amount * needed in BytesNeeded and return NDIS_STATUS_INVALID_LENGTH * TODO: * - Update to verify input buffer & size and return insufficient buffer codes */{ NDIS_STATUS Status; PVOID CopyFrom; UINT CopySize; ULONG GenericULONG; PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
DPRINT("Called. OID 0x%x\n", Oid);
ASSERT(Adapter);
NdisAcquireSpinLock(&Adapter->Lock);
Status = NDIS_STATUS_SUCCESS; CopyFrom = (PVOID)&GenericULONG; CopySize = sizeof(ULONG);
switch (Oid) { case OID_GEN_SUPPORTED_LIST: { CopyFrom = (PVOID)&MiniportOIDList; CopySize = sizeof(MiniportOIDList); break; }
case OID_GEN_HARDWARE_STATUS: { GenericULONG = (ULONG)NdisHardwareStatusReady; break; }
case OID_GEN_MEDIA_SUPPORTED: case OID_GEN_MEDIA_IN_USE: { 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; break; }
case OID_GEN_MAXIMUM_FRAME_SIZE: { /* * The value returned by this OID must be equal to * OID_GEN_MAXIMUM_TOTAL_SIZE - sizeof(ETHERNET_HEADER) * where sizeof(ETHERNET_HEADER) is 14. */ GenericULONG = 1500; break; }
case OID_GEN_LINK_SPEED: { GenericULONG = Adapter->MediaSpeed * 10000; break; }
case OID_GEN_TRANSMIT_BUFFER_SPACE: { /* XXX fix me */ GenericULONG = BUFFER_SIZE; break; }
case OID_GEN_RECEIVE_BUFFER_SPACE: { /* XXX fix me */ GenericULONG = BUFFER_SIZE; break; }
case OID_GEN_TRANSMIT_BLOCK_SIZE: { GenericULONG = BUFFER_SIZE; break; }
case OID_GEN_RECEIVE_BLOCK_SIZE: { GenericULONG = BUFFER_SIZE; break; }
case OID_GEN_VENDOR_ID: { UCHAR *CharPtr = (UCHAR *)&GenericULONG; GenericULONG = 0; /* Read the first three bytes of the permanent MAC address */ NdisRawReadPortUchar(Adapter->PortOffset, CharPtr); NdisRawReadPortUchar(Adapter->PortOffset + 1, CharPtr + 1); NdisRawReadPortUchar(Adapter->PortOffset + 2, CharPtr + 2); break; }
case OID_GEN_VENDOR_DESCRIPTION: { static UCHAR VendorDesc[] = "ReactOS Team"; CopyFrom = VendorDesc; CopySize = sizeof(VendorDesc); break; }
case OID_GEN_VENDOR_DRIVER_VERSION: { /* XXX implement me */ GenericULONG = 1; break; }
case OID_GEN_CURRENT_PACKET_FILTER: { GenericULONG = Adapter->CurrentPacketFilter; break; }
case OID_GEN_DRIVER_VERSION: { /* NDIS version used by the driver. */ static const USHORT DriverVersion = (NDIS_MINIPORT_MAJOR_VERSION << 8) + NDIS_MINIPORT_MINOR_VERSION; CopyFrom = (PVOID)&DriverVersion; CopySize = sizeof(DriverVersion); break; }
case OID_GEN_MAXIMUM_TOTAL_SIZE: { /* See comment in OID_GEN_MAXIMUM_FRAME_SIZE. */ GenericULONG = 1514; break; }
case OID_GEN_PROTOCOL_OPTIONS: { DPRINT("OID_GEN_PROTOCOL_OPTIONS.\n"); Status = NDIS_STATUS_NOT_SUPPORTED; break; }
case OID_GEN_MAC_OPTIONS: { GenericULONG = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | NDIS_MAC_OPTION_RECEIVE_SERIALIZED | NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | NDIS_MAC_OPTION_NO_LOOPBACK; break; }
case OID_GEN_MEDIA_CONNECT_STATUS: { GenericULONG = (ULONG)NdisMediaStateConnected; /* Adapter->MediaState */ break; }
case OID_GEN_MAXIMUM_SEND_PACKETS: { GenericULONG = 1; break; }
case OID_802_3_CURRENT_ADDRESS: case OID_802_3_PERMANENT_ADDRESS: { CopyFrom = (PVOID)&Adapter->InitializationBlockVirt->PADR; CopySize = 6; break; }
case OID_802_3_MAXIMUM_LIST_SIZE: { GenericULONG = MAX_MULTICAST_ADDRESSES; break; }
case OID_GEN_XMIT_OK: GenericULONG = Adapter->Statistics.XmtGoodFrames; break;
case OID_GEN_RCV_OK: GenericULONG = Adapter->Statistics.RcvGoodFrames; break;
case OID_GEN_XMIT_ERROR: GenericULONG = Adapter->Statistics.XmtRetryErrors + Adapter->Statistics.XmtLossesOfCarrier + Adapter->Statistics.XmtCollisions + Adapter->Statistics.XmtLateCollisions + Adapter->Statistics.XmtExcessiveDeferrals + Adapter->Statistics.XmtBufferUnderflows + Adapter->Statistics.XmtBufferErrors; break;
case OID_GEN_RCV_ERROR: GenericULONG = Adapter->Statistics.RcvBufferErrors + Adapter->Statistics.RcvCrcErrors + Adapter->Statistics.RcvOverflowErrors + Adapter->Statistics.RcvFramingErrors; break;
case OID_GEN_RCV_NO_BUFFER: GenericULONG = Adapter->Statistics.RcvBufferErrors + Adapter->Statistics.RcvOverflowErrors; break;
case OID_GEN_RCV_CRC_ERROR: GenericULONG = Adapter->Statistics.RcvCrcErrors; break;
case OID_802_3_RCV_ERROR_ALIGNMENT: GenericULONG = Adapter->Statistics.RcvFramingErrors; break;
case OID_802_3_XMIT_ONE_COLLISION: GenericULONG = Adapter->Statistics.XmtOneRetry; break;
case OID_802_3_XMIT_MORE_COLLISIONS: GenericULONG = Adapter->Statistics.XmtMoreThanOneRetry; break;
case OID_GEN_PHYSICAL_MEDIUM: GenericULONG = NdisPhysicalMedium802_3; break;
default: { DPRINT1("Unknown OID 0x%x\n", Oid); Status = NDIS_STATUS_NOT_SUPPORTED; break; } }
if (Status == NDIS_STATUS_SUCCESS) { if (CopySize > InformationBufferLength) { *BytesNeeded = CopySize; *BytesWritten = 0; Status = NDIS_STATUS_INVALID_LENGTH; } else { NdisMoveMemory(InformationBuffer, CopyFrom, CopySize); *BytesWritten = CopySize; *BytesNeeded = CopySize; } } else { *BytesWritten = 0; *BytesNeeded = 0; }
NdisReleaseSpinLock(&Adapter->Lock);
DPRINT("Leaving. Status is 0x%x\n", Status);
return Status;}
NDIS_STATUSNTAPIMiniportSetInformation( IN NDIS_HANDLE MiniportAdapterContext, IN NDIS_OID Oid, IN PVOID InformationBuffer, IN ULONG InformationBufferLength, OUT PULONG BytesRead, OUT PULONG BytesNeeded)/* * FUNCTION: Set a miniport variable (OID) * ARGUMENTS: * MiniportAdapterContext: context originally passed into NdisMSetAttributes * Oid: the variable being set * InformationBuffer: the data to set the variable to * InformationBufferLength: number of bytes in InformationBuffer * BytesRead: number of bytes read by us out of the buffer * BytesNeeded: number of bytes required to satisfy the request if InformationBufferLength * is insufficient * RETURNS: * NDIS_STATUS_SUCCESS on all requests * NOTES: * - Called by NDIS at DISPATCH_LEVEL * - verify buffer space as mentioned in previous function notes */{ ULONG GenericULONG; NDIS_STATUS Status = NDIS_STATUS_SUCCESS; PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
ASSERT(Adapter);
DPRINT("Called, OID 0x%x\n", Oid);
NdisAcquireSpinLock(&Adapter->Lock);
switch (Oid) { case OID_GEN_CURRENT_PACKET_FILTER: { /* Verify length */ if (InformationBufferLength < sizeof(ULONG)) { *BytesRead = 0; *BytesNeeded = sizeof(ULONG); Status = NDIS_STATUS_INVALID_LENGTH; break; }
NdisMoveMemory(&GenericULONG, InformationBuffer, sizeof(ULONG));
/* Check for properties the driver don't support */ 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 = 0; Status = NDIS_STATUS_NOT_SUPPORTED; break; }
Adapter->CurrentPacketFilter = GenericULONG;
/* FIXME: Set filter on hardware */
break; }
case OID_GEN_CURRENT_LOOKAHEAD: { /* Verify length */ if (InformationBufferLength < sizeof(ULONG)) { *BytesRead = 0; *BytesNeeded = sizeof(ULONG); Status = NDIS_STATUS_INVALID_LENGTH; break; }
NdisMoveMemory(&GenericULONG, InformationBuffer, sizeof(ULONG));
if (GenericULONG > 1500) Status = NDIS_STATUS_INVALID_DATA; else Adapter->CurrentLookaheadSize = GenericULONG;
break; }
case OID_802_3_MULTICAST_LIST: { /* Verify length. Must be multiple of hardware address length */ if ((InformationBufferLength % 6) != 0) { *BytesRead = 0; *BytesNeeded = InformationBufferLength + (InformationBufferLength % 6); Status = NDIS_STATUS_INVALID_LENGTH; break; }
ASSERT((InformationBufferLength / 6) <= MAX_MULTICAST_ADDRESSES);
/* Set new multicast address list */ //NdisMoveMemory(Adapter->Addresses, InformationBuffer, InformationBufferLength);
/* Update hardware */ Status = MiSetMulticast(Adapter, InformationBuffer, InformationBufferLength / 6);
break; }
default: { DPRINT1("Invalid object ID (0x%X).\n", Oid); *BytesRead = 0; *BytesNeeded = 0; Status = NDIS_STATUS_NOT_SUPPORTED; break; } }
if (Status == NDIS_STATUS_SUCCESS) { *BytesRead = InformationBufferLength; *BytesNeeded = 0; }
NdisReleaseSpinLock(&Adapter->Lock);
DPRINT("Leaving. Status (0x%X).\n", Status);
return Status;}