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
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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
43 /* List of supported OIDs */
44 static ULONG MiniportOIDList
[] =
46 OID_GEN_SUPPORTED_LIST
,
47 OID_GEN_HARDWARE_STATUS
,
48 OID_GEN_MEDIA_SUPPORTED
,
50 OID_GEN_MAXIMUM_LOOKAHEAD
,
51 OID_GEN_MAXIMUM_FRAME_SIZE
,
53 OID_GEN_TRANSMIT_BUFFER_SPACE
,
54 OID_GEN_RECEIVE_BUFFER_SPACE
,
55 OID_GEN_TRANSMIT_BLOCK_SIZE
,
56 OID_GEN_RECEIVE_BLOCK_SIZE
,
58 OID_GEN_VENDOR_DESCRIPTION
,
59 OID_GEN_VENDOR_DRIVER_VERSION
,
60 OID_GEN_CURRENT_PACKET_FILTER
,
61 OID_GEN_CURRENT_LOOKAHEAD
,
62 OID_GEN_DRIVER_VERSION
,
63 OID_GEN_MAXIMUM_TOTAL_SIZE
,
64 OID_GEN_PROTOCOL_OPTIONS
,
66 OID_GEN_MEDIA_CONNECT_STATUS
,
67 OID_GEN_MAXIMUM_SEND_PACKETS
,
72 OID_GEN_RCV_NO_BUFFER
,
73 OID_GEN_RCV_CRC_ERROR
,
74 OID_802_3_PERMANENT_ADDRESS
,
75 OID_802_3_CURRENT_ADDRESS
,
76 OID_802_3_MULTICAST_LIST
,
77 OID_802_3_MAXIMUM_LIST_SIZE
,
78 OID_802_3_MAC_OPTIONS
,
79 OID_802_3_RCV_ERROR_ALIGNMENT
,
80 OID_802_3_XMIT_ONE_COLLISION
,
81 OID_802_3_XMIT_MORE_COLLISIONS
87 MiniportQueryInformation(
88 IN NDIS_HANDLE MiniportAdapterContext
,
90 IN PVOID InformationBuffer
,
91 IN ULONG InformationBufferLength
,
92 OUT PULONG BytesWritten
,
93 OUT PULONG BytesNeeded
)
95 * FUNCTION: Query an OID from the driver
97 * MiniportAdapterContext: context originally passed to NdisMSetAttributes
98 * Oid: OID NDIS is querying
99 * InformationBuffer: pointer to buffer into which to write the results of the query
100 * InformationBufferLength: size in bytes of InformationBuffer
101 * BytesWritten: number of bytes written into InformationBuffer in response to the query
102 * BytesNeeded: number of bytes needed to answer the query
104 * NDIS_STATUS_SUCCESS on all queries
106 * - Called by NDIS at PASSIVE_LEVEL
107 * - If InformationBufferLength is insufficient to store the results, return the amount
108 * needed in BytesNeeded and return NDIS_STATUS_INVALID_LENGTH
110 * - Update to verify input buffer & size and return insufficient buffer codes
117 PADAPTER Adapter
= (PADAPTER
)MiniportAdapterContext
;
119 DPRINT("Called. OID 0x%x\n", Oid
);
123 NdisAcquireSpinLock(&Adapter
->Lock
);
125 Status
= NDIS_STATUS_SUCCESS
;
126 CopyFrom
= (PVOID
)&GenericULONG
;
127 CopySize
= sizeof(ULONG
);
131 case OID_GEN_SUPPORTED_LIST
:
133 CopyFrom
= (PVOID
)&MiniportOIDList
;
134 CopySize
= sizeof(MiniportOIDList
);
138 case OID_GEN_HARDWARE_STATUS
:
140 /* TODO: implement this... */
141 GenericULONG
= (ULONG
)NdisHardwareStatusReady
;
145 case OID_GEN_MEDIA_SUPPORTED
:
146 case OID_GEN_MEDIA_IN_USE
:
148 static const NDIS_MEDIUM Medium
= NdisMedium802_3
;
149 CopyFrom
= (PVOID
)&Medium
;
150 CopySize
= sizeof(NDIS_MEDIUM
);
154 case OID_GEN_CURRENT_LOOKAHEAD
:
155 case OID_GEN_MAXIMUM_LOOKAHEAD
:
161 case OID_GEN_MAXIMUM_FRAME_SIZE
:
164 * The value returned by this OID must be equal to
165 * OID_GEN_MAXIMUM_TOTAL_SIZE - sizeof(ETHERNET_HEADER)
166 * where sizeof(ETHERNET_HEADER) is 14.
172 case OID_GEN_LINK_SPEED
:
174 GenericULONG
= 100000; /* 10Mbps */
178 case OID_GEN_TRANSMIT_BUFFER_SPACE
:
181 GenericULONG
= BUFFER_SIZE
;
185 case OID_GEN_RECEIVE_BUFFER_SPACE
:
188 GenericULONG
= BUFFER_SIZE
;
192 case OID_GEN_TRANSMIT_BLOCK_SIZE
:
194 GenericULONG
= BUFFER_SIZE
;
198 case OID_GEN_RECEIVE_BLOCK_SIZE
:
200 GenericULONG
= BUFFER_SIZE
;
204 case OID_GEN_VENDOR_ID
:
206 UCHAR
*CharPtr
= (UCHAR
*)&GenericULONG
;
208 /* Read the first three bytes of the permanent MAC address */
209 NdisRawReadPortUchar(Adapter
->PortOffset
, CharPtr
);
210 NdisRawReadPortUchar(Adapter
->PortOffset
+ 1, CharPtr
+ 1);
211 NdisRawReadPortUchar(Adapter
->PortOffset
+ 2, CharPtr
+ 2);
215 case OID_GEN_VENDOR_DESCRIPTION
:
217 static UCHAR VendorDesc
[] = "ReactOS Team";
218 CopyFrom
= VendorDesc
;
219 CopySize
= sizeof(VendorDesc
);
223 case OID_GEN_VENDOR_DRIVER_VERSION
:
225 /* XXX implement me */
230 case OID_GEN_CURRENT_PACKET_FILTER
:
232 GenericULONG
= Adapter
->CurrentPacketFilter
;
236 case OID_GEN_DRIVER_VERSION
:
238 /* NDIS version used by the driver. */
239 static const USHORT DriverVersion
=
240 (NDIS_MINIPORT_MAJOR_VERSION
<< 8) + NDIS_MINIPORT_MINOR_VERSION
;
241 CopyFrom
= (PVOID
)&DriverVersion
;
242 CopySize
= sizeof(DriverVersion
);
246 case OID_GEN_MAXIMUM_TOTAL_SIZE
:
248 /* See comment in OID_GEN_MAXIMUM_FRAME_SIZE. */
253 case OID_GEN_PROTOCOL_OPTIONS
:
255 DPRINT("OID_GEN_PROTOCOL_OPTIONS.\n");
256 Status
= NDIS_STATUS_NOT_SUPPORTED
;
260 case OID_GEN_MAC_OPTIONS
:
262 GenericULONG
= NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
|
263 NDIS_MAC_OPTION_RECEIVE_SERIALIZED
|
264 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND
;
268 case OID_GEN_MEDIA_CONNECT_STATUS
:
270 GenericULONG
= Adapter
->MediaState
;
274 case OID_GEN_MAXIMUM_SEND_PACKETS
:
280 case OID_802_3_CURRENT_ADDRESS
:
281 case OID_802_3_PERMANENT_ADDRESS
:
283 CopyFrom
= (PVOID
)&Adapter
->InitializationBlockVirt
->PADR
;
288 case OID_802_3_MAXIMUM_LIST_SIZE
:
290 GenericULONG
= MAX_MULTICAST_ADDRESSES
;
294 case OID_GEN_XMIT_OK
:
295 GenericULONG
= Adapter
->Statistics
.XmtGoodFrames
;
299 GenericULONG
= Adapter
->Statistics
.RcvGoodFrames
;
302 case OID_GEN_XMIT_ERROR
:
303 GenericULONG
= Adapter
->Statistics
.XmtRetryErrors
+
304 Adapter
->Statistics
.XmtLossesOfCarrier
+
305 Adapter
->Statistics
.XmtCollisions
+
306 Adapter
->Statistics
.XmtLateCollisions
+
307 Adapter
->Statistics
.XmtExcessiveDefferals
+
308 Adapter
->Statistics
.XmtBufferUnderflows
+
309 Adapter
->Statistics
.XmtBufferErrors
;
312 case OID_GEN_RCV_ERROR
:
313 GenericULONG
= Adapter
->Statistics
.RcvBufferErrors
+
314 Adapter
->Statistics
.RcvCrcErrors
+
315 Adapter
->Statistics
.RcvOverflowErrors
+
316 Adapter
->Statistics
.RcvFramingErrors
;
319 case OID_GEN_RCV_NO_BUFFER
:
320 GenericULONG
= Adapter
->Statistics
.RcvBufferErrors
+
321 Adapter
->Statistics
.RcvOverflowErrors
;
324 case OID_GEN_RCV_CRC_ERROR
:
325 GenericULONG
= Adapter
->Statistics
.RcvCrcErrors
;
328 case OID_802_3_RCV_ERROR_ALIGNMENT
:
329 GenericULONG
= Adapter
->Statistics
.RcvFramingErrors
;
332 case OID_802_3_XMIT_ONE_COLLISION
:
333 GenericULONG
= Adapter
->Statistics
.XmtOneRetry
;
336 case OID_802_3_XMIT_MORE_COLLISIONS
:
337 GenericULONG
= Adapter
->Statistics
.XmtMoreThanOneRetry
;
342 DPRINT1("Unknown OID\n");
343 Status
= NDIS_STATUS_NOT_SUPPORTED
;
348 if (Status
== NDIS_STATUS_SUCCESS
)
350 if (CopySize
> InformationBufferLength
)
352 *BytesNeeded
= (CopySize
- InformationBufferLength
);
354 Status
= NDIS_STATUS_BUFFER_TOO_SHORT
;
358 NdisMoveMemory(InformationBuffer
, CopyFrom
, CopySize
);
359 *BytesWritten
= CopySize
;
360 *BytesNeeded
= CopySize
;
364 NdisReleaseSpinLock(&Adapter
->Lock
);
366 DPRINT("Leaving. Status is 0x%x\n", Status
);
373 MiniportSetInformation(
374 IN NDIS_HANDLE MiniportAdapterContext
,
376 IN PVOID InformationBuffer
,
377 IN ULONG InformationBufferLength
,
378 OUT PULONG BytesRead
,
379 OUT PULONG BytesNeeded
)
381 * FUNCTION: Set a miniport variable (OID)
383 * MiniportAdapterContext: context originally passed into NdisMSetAttributes
384 * Oid: the variable being set
385 * InformationBuffer: the data to set the variable to
386 * InformationBufferLength: number of bytes in InformationBuffer
387 * BytesRead: number of bytes read by us out of the buffer
388 * BytesNeeded: number of bytes required to satisfy the request if InformationBufferLength
391 * NDIS_STATUS_SUCCESS on all requests
393 * - Called by NDIS at PASSIVE_LEVEL
394 * - verify buffer space as mentioned in previous function notes
398 NDIS_STATUS Status
= NDIS_STATUS_SUCCESS
;
399 PADAPTER Adapter
= (PADAPTER
)MiniportAdapterContext
;
403 DPRINT("Called, OID 0x%x\n", Oid
);
405 NdisAcquireSpinLock(&Adapter
->Lock
);
409 case OID_GEN_CURRENT_PACKET_FILTER
:
412 if (InformationBufferLength
< sizeof(ULONG
))
415 *BytesNeeded
= sizeof(ULONG
) - InformationBufferLength
;
416 Status
= NDIS_STATUS_INVALID_LENGTH
;
420 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
422 /* Check for properties the driver don't support */
424 (NDIS_PACKET_TYPE_ALL_FUNCTIONAL
|
425 NDIS_PACKET_TYPE_FUNCTIONAL
|
426 NDIS_PACKET_TYPE_GROUP
|
427 NDIS_PACKET_TYPE_MAC_FRAME
|
428 NDIS_PACKET_TYPE_SMT
|
429 NDIS_PACKET_TYPE_SOURCE_ROUTING
)
434 Status
= NDIS_STATUS_NOT_SUPPORTED
;
438 Adapter
->CurrentPacketFilter
= GenericULONG
;
440 /* FIXME: Set filter on hardware */
445 case OID_GEN_CURRENT_LOOKAHEAD
:
448 if (InformationBufferLength
< sizeof(ULONG
))
451 *BytesNeeded
= sizeof(ULONG
) - InformationBufferLength
;
452 Status
= NDIS_STATUS_INVALID_LENGTH
;
456 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
458 if (GenericULONG
> 1500)
459 Status
= NDIS_STATUS_INVALID_LENGTH
;
461 Adapter
->CurrentLookaheadSize
= GenericULONG
;
466 case OID_802_3_MULTICAST_LIST
:
468 /* Verify length. Must be multiple of hardware address length */
469 if ((InformationBufferLength
% 6) != 0)
473 Status
= NDIS_STATUS_INVALID_LENGTH
;
477 ASSERT((InformationBufferLength
/ 6) <= MAX_MULTICAST_ADDRESSES
);
479 /* Set new multicast address list */
480 //NdisMoveMemory(Adapter->Addresses, InformationBuffer, InformationBufferLength);
482 /* Update hardware */
483 Status
= MiSetMulticast(Adapter
, InformationBuffer
, InformationBufferLength
/ 6);
490 DPRINT1("Invalid object ID (0x%X).\n", Oid
);
493 Status
= NDIS_STATUS_NOT_SUPPORTED
;
498 if (Status
== NDIS_STATUS_SUCCESS
)
500 *BytesRead
= InformationBufferLength
;
504 NdisReleaseSpinLock(&Adapter
->Lock
);
506 DPRINT("Leaving. Status (0x%X).\n", Status
);