2 * ReactOS AMD PCNet Driver
4 * Copyright (C) 2000 Casper Hornstroup <chorns@users.sourceforge.net>
5 * Copyright (C) 2003 Vizzini <vizzini@plasmic.com>
6 * Copyright (C) 2004 Filip Navara <navaraf@reactos.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 * Vizzini (vizzini@plasmic.com),
24 * borrowed very heavily from the ReactOS ne2000 driver by
25 * Casper S. Hornstrup (chorns@users.sourceforge.net)
27 * 14-Sep-2003 vizzini - Created
28 * 17-Oct-2004 navaraf - Add multicast support.
29 * - Add media state detection support.
30 * - Protect the adapter context with spinlock
31 * and move code talking to card to inside
32 * NdisMSynchronizeWithInterrupt calls where
41 /* List of supported OIDs */
42 static ULONG MiniportOIDList
[] =
44 OID_GEN_SUPPORTED_LIST
,
45 OID_GEN_HARDWARE_STATUS
,
46 OID_GEN_MEDIA_SUPPORTED
,
48 OID_GEN_MAXIMUM_LOOKAHEAD
,
49 OID_GEN_MAXIMUM_FRAME_SIZE
,
51 OID_GEN_TRANSMIT_BUFFER_SPACE
,
52 OID_GEN_RECEIVE_BUFFER_SPACE
,
53 OID_GEN_TRANSMIT_BLOCK_SIZE
,
54 OID_GEN_RECEIVE_BLOCK_SIZE
,
56 OID_GEN_VENDOR_DESCRIPTION
,
57 OID_GEN_VENDOR_DRIVER_VERSION
,
58 OID_GEN_CURRENT_PACKET_FILTER
,
59 OID_GEN_CURRENT_LOOKAHEAD
,
60 OID_GEN_DRIVER_VERSION
,
61 OID_GEN_MAXIMUM_TOTAL_SIZE
,
62 OID_GEN_PROTOCOL_OPTIONS
,
64 OID_GEN_MEDIA_CONNECT_STATUS
,
65 OID_GEN_MAXIMUM_SEND_PACKETS
,
70 OID_GEN_RCV_NO_BUFFER
,
71 OID_GEN_RCV_CRC_ERROR
,
72 OID_802_3_PERMANENT_ADDRESS
,
73 OID_802_3_CURRENT_ADDRESS
,
74 OID_802_3_MULTICAST_LIST
,
75 OID_802_3_MAXIMUM_LIST_SIZE
,
76 OID_802_3_MAC_OPTIONS
,
77 OID_802_3_RCV_ERROR_ALIGNMENT
,
78 OID_802_3_XMIT_ONE_COLLISION
,
79 OID_802_3_XMIT_MORE_COLLISIONS
85 MiniportQueryInformation(
86 IN NDIS_HANDLE MiniportAdapterContext
,
88 IN PVOID InformationBuffer
,
89 IN ULONG InformationBufferLength
,
90 OUT PULONG BytesWritten
,
91 OUT PULONG BytesNeeded
)
93 * FUNCTION: Query an OID from the driver
95 * MiniportAdapterContext: context originally passed to NdisMSetAttributes
96 * Oid: OID NDIS is querying
97 * InformationBuffer: pointer to buffer into which to write the results of the query
98 * InformationBufferLength: size in bytes of InformationBuffer
99 * BytesWritten: number of bytes written into InformationBuffer in response to the query
100 * BytesNeeded: number of bytes needed to answer the query
102 * NDIS_STATUS_SUCCESS on all queries
104 * - Called by NDIS at DISPATCH_LEVEL
105 * - If InformationBufferLength is insufficient to store the results, return the amount
106 * needed in BytesNeeded and return NDIS_STATUS_INVALID_LENGTH
108 * - Update to verify input buffer & size and return insufficient buffer codes
115 PADAPTER Adapter
= (PADAPTER
)MiniportAdapterContext
;
117 DPRINT("Called. OID 0x%x\n", Oid
);
121 NdisAcquireSpinLock(&Adapter
->Lock
);
123 Status
= NDIS_STATUS_SUCCESS
;
124 CopyFrom
= (PVOID
)&GenericULONG
;
125 CopySize
= sizeof(ULONG
);
129 case OID_GEN_SUPPORTED_LIST
:
131 CopyFrom
= (PVOID
)&MiniportOIDList
;
132 CopySize
= sizeof(MiniportOIDList
);
136 case OID_GEN_HARDWARE_STATUS
:
138 GenericULONG
= (ULONG
)NdisHardwareStatusReady
;
139 /* ((Adapter->MediaState == NdisMediaStateConnected) ? NdisHardwareStatusReady : NdisHardwareStatusNotReady); */
143 case OID_GEN_MEDIA_SUPPORTED
:
144 case OID_GEN_MEDIA_IN_USE
:
146 static const NDIS_MEDIUM Medium
= NdisMedium802_3
;
147 CopyFrom
= (PVOID
)&Medium
;
148 CopySize
= sizeof(NDIS_MEDIUM
);
152 case OID_GEN_CURRENT_LOOKAHEAD
:
153 case OID_GEN_MAXIMUM_LOOKAHEAD
:
159 case OID_GEN_MAXIMUM_FRAME_SIZE
:
162 * The value returned by this OID must be equal to
163 * OID_GEN_MAXIMUM_TOTAL_SIZE - sizeof(ETHERNET_HEADER)
164 * where sizeof(ETHERNET_HEADER) is 14.
170 case OID_GEN_LINK_SPEED
:
172 GenericULONG
= Adapter
->MediaSpeed
* 10000;
176 case OID_GEN_TRANSMIT_BUFFER_SPACE
:
179 GenericULONG
= BUFFER_SIZE
;
183 case OID_GEN_RECEIVE_BUFFER_SPACE
:
186 GenericULONG
= BUFFER_SIZE
;
190 case OID_GEN_TRANSMIT_BLOCK_SIZE
:
192 GenericULONG
= BUFFER_SIZE
;
196 case OID_GEN_RECEIVE_BLOCK_SIZE
:
198 GenericULONG
= BUFFER_SIZE
;
202 case OID_GEN_VENDOR_ID
:
204 UCHAR
*CharPtr
= (UCHAR
*)&GenericULONG
;
206 /* Read the first three bytes of the permanent MAC address */
207 NdisRawReadPortUchar(Adapter
->PortOffset
, CharPtr
);
208 NdisRawReadPortUchar(Adapter
->PortOffset
+ 1, CharPtr
+ 1);
209 NdisRawReadPortUchar(Adapter
->PortOffset
+ 2, CharPtr
+ 2);
213 case OID_GEN_VENDOR_DESCRIPTION
:
215 static UCHAR VendorDesc
[] = "ReactOS Team";
216 CopyFrom
= VendorDesc
;
217 CopySize
= sizeof(VendorDesc
);
221 case OID_GEN_VENDOR_DRIVER_VERSION
:
223 /* XXX implement me */
228 case OID_GEN_CURRENT_PACKET_FILTER
:
230 GenericULONG
= Adapter
->CurrentPacketFilter
;
234 case OID_GEN_DRIVER_VERSION
:
236 /* NDIS version used by the driver. */
237 static const USHORT DriverVersion
=
238 (NDIS_MINIPORT_MAJOR_VERSION
<< 8) + NDIS_MINIPORT_MINOR_VERSION
;
239 CopyFrom
= (PVOID
)&DriverVersion
;
240 CopySize
= sizeof(DriverVersion
);
244 case OID_GEN_MAXIMUM_TOTAL_SIZE
:
246 /* See comment in OID_GEN_MAXIMUM_FRAME_SIZE. */
251 case OID_GEN_PROTOCOL_OPTIONS
:
253 DPRINT("OID_GEN_PROTOCOL_OPTIONS.\n");
254 Status
= NDIS_STATUS_NOT_SUPPORTED
;
258 case OID_GEN_MAC_OPTIONS
:
260 GenericULONG
= NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
|
261 NDIS_MAC_OPTION_RECEIVE_SERIALIZED
|
262 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND
|
263 NDIS_MAC_OPTION_NO_LOOPBACK
;
267 case OID_GEN_MEDIA_CONNECT_STATUS
:
269 GenericULONG
= (ULONG
)NdisMediaStateConnected
; /* Adapter->MediaState */
273 case OID_GEN_MAXIMUM_SEND_PACKETS
:
279 case OID_802_3_CURRENT_ADDRESS
:
280 case OID_802_3_PERMANENT_ADDRESS
:
282 CopyFrom
= (PVOID
)&Adapter
->InitializationBlockVirt
->PADR
;
287 case OID_802_3_MAXIMUM_LIST_SIZE
:
289 GenericULONG
= MAX_MULTICAST_ADDRESSES
;
293 case OID_GEN_XMIT_OK
:
294 GenericULONG
= Adapter
->Statistics
.XmtGoodFrames
;
298 GenericULONG
= Adapter
->Statistics
.RcvGoodFrames
;
301 case OID_GEN_XMIT_ERROR
:
302 GenericULONG
= Adapter
->Statistics
.XmtRetryErrors
+
303 Adapter
->Statistics
.XmtLossesOfCarrier
+
304 Adapter
->Statistics
.XmtCollisions
+
305 Adapter
->Statistics
.XmtLateCollisions
+
306 Adapter
->Statistics
.XmtExcessiveDefferals
+
307 Adapter
->Statistics
.XmtBufferUnderflows
+
308 Adapter
->Statistics
.XmtBufferErrors
;
311 case OID_GEN_RCV_ERROR
:
312 GenericULONG
= Adapter
->Statistics
.RcvBufferErrors
+
313 Adapter
->Statistics
.RcvCrcErrors
+
314 Adapter
->Statistics
.RcvOverflowErrors
+
315 Adapter
->Statistics
.RcvFramingErrors
;
318 case OID_GEN_RCV_NO_BUFFER
:
319 GenericULONG
= Adapter
->Statistics
.RcvBufferErrors
+
320 Adapter
->Statistics
.RcvOverflowErrors
;
323 case OID_GEN_RCV_CRC_ERROR
:
324 GenericULONG
= Adapter
->Statistics
.RcvCrcErrors
;
327 case OID_802_3_RCV_ERROR_ALIGNMENT
:
328 GenericULONG
= Adapter
->Statistics
.RcvFramingErrors
;
331 case OID_802_3_XMIT_ONE_COLLISION
:
332 GenericULONG
= Adapter
->Statistics
.XmtOneRetry
;
335 case OID_802_3_XMIT_MORE_COLLISIONS
:
336 GenericULONG
= Adapter
->Statistics
.XmtMoreThanOneRetry
;
341 DPRINT1("Unknown OID\n");
342 Status
= NDIS_STATUS_NOT_SUPPORTED
;
347 if (Status
== NDIS_STATUS_SUCCESS
)
349 if (CopySize
> InformationBufferLength
)
351 *BytesNeeded
= CopySize
;
353 Status
= NDIS_STATUS_INVALID_LENGTH
;
357 NdisMoveMemory(InformationBuffer
, CopyFrom
, CopySize
);
358 *BytesWritten
= CopySize
;
359 *BytesNeeded
= CopySize
;
368 NdisReleaseSpinLock(&Adapter
->Lock
);
370 DPRINT("Leaving. Status is 0x%x\n", Status
);
377 MiniportSetInformation(
378 IN NDIS_HANDLE MiniportAdapterContext
,
380 IN PVOID InformationBuffer
,
381 IN ULONG InformationBufferLength
,
382 OUT PULONG BytesRead
,
383 OUT PULONG BytesNeeded
)
385 * FUNCTION: Set a miniport variable (OID)
387 * MiniportAdapterContext: context originally passed into NdisMSetAttributes
388 * Oid: the variable being set
389 * InformationBuffer: the data to set the variable to
390 * InformationBufferLength: number of bytes in InformationBuffer
391 * BytesRead: number of bytes read by us out of the buffer
392 * BytesNeeded: number of bytes required to satisfy the request if InformationBufferLength
395 * NDIS_STATUS_SUCCESS on all requests
397 * - Called by NDIS at DISPATCH_LEVEL
398 * - verify buffer space as mentioned in previous function notes
402 NDIS_STATUS Status
= NDIS_STATUS_SUCCESS
;
403 PADAPTER Adapter
= (PADAPTER
)MiniportAdapterContext
;
407 DPRINT("Called, OID 0x%x\n", Oid
);
409 NdisAcquireSpinLock(&Adapter
->Lock
);
413 case OID_GEN_CURRENT_PACKET_FILTER
:
416 if (InformationBufferLength
< sizeof(ULONG
))
419 *BytesNeeded
= sizeof(ULONG
);
420 Status
= NDIS_STATUS_INVALID_LENGTH
;
424 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
426 /* Check for properties the driver don't support */
428 (NDIS_PACKET_TYPE_ALL_FUNCTIONAL
|
429 NDIS_PACKET_TYPE_FUNCTIONAL
|
430 NDIS_PACKET_TYPE_GROUP
|
431 NDIS_PACKET_TYPE_MAC_FRAME
|
432 NDIS_PACKET_TYPE_SMT
|
433 NDIS_PACKET_TYPE_SOURCE_ROUTING
)
436 *BytesRead
= sizeof(ULONG
);
438 Status
= NDIS_STATUS_NOT_SUPPORTED
;
442 Adapter
->CurrentPacketFilter
= GenericULONG
;
444 /* FIXME: Set filter on hardware */
449 case OID_GEN_CURRENT_LOOKAHEAD
:
452 if (InformationBufferLength
< sizeof(ULONG
))
455 *BytesNeeded
= sizeof(ULONG
);
456 Status
= NDIS_STATUS_INVALID_LENGTH
;
460 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
462 if (GenericULONG
> 1500)
463 Status
= NDIS_STATUS_INVALID_DATA
;
465 Adapter
->CurrentLookaheadSize
= GenericULONG
;
470 case OID_802_3_MULTICAST_LIST
:
472 /* Verify length. Must be multiple of hardware address length */
473 if ((InformationBufferLength
% 6) != 0)
476 *BytesNeeded
= InformationBufferLength
+ (InformationBufferLength
% 6);
477 Status
= NDIS_STATUS_INVALID_LENGTH
;
481 ASSERT((InformationBufferLength
/ 6) <= MAX_MULTICAST_ADDRESSES
);
483 /* Set new multicast address list */
484 //NdisMoveMemory(Adapter->Addresses, InformationBuffer, InformationBufferLength);
486 /* Update hardware */
487 Status
= MiSetMulticast(Adapter
, InformationBuffer
, InformationBufferLength
/ 6);
494 DPRINT1("Invalid object ID (0x%X).\n", Oid
);
497 Status
= NDIS_STATUS_NOT_SUPPORTED
;
502 if (Status
== NDIS_STATUS_SUCCESS
)
504 *BytesRead
= InformationBufferLength
;
508 NdisReleaseSpinLock(&Adapter
->Lock
);
510 DPRINT("Leaving. Status (0x%X).\n", Status
);