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
;
142 case OID_GEN_MEDIA_SUPPORTED
:
143 case OID_GEN_MEDIA_IN_USE
:
145 static const NDIS_MEDIUM Medium
= NdisMedium802_3
;
146 CopyFrom
= (PVOID
)&Medium
;
147 CopySize
= sizeof(NDIS_MEDIUM
);
151 case OID_GEN_CURRENT_LOOKAHEAD
:
152 case OID_GEN_MAXIMUM_LOOKAHEAD
:
158 case OID_GEN_MAXIMUM_FRAME_SIZE
:
161 * The value returned by this OID must be equal to
162 * OID_GEN_MAXIMUM_TOTAL_SIZE - sizeof(ETHERNET_HEADER)
163 * where sizeof(ETHERNET_HEADER) is 14.
169 case OID_GEN_LINK_SPEED
:
171 GenericULONG
= Adapter
->MediaSpeed
* 10000;
175 case OID_GEN_TRANSMIT_BUFFER_SPACE
:
178 GenericULONG
= BUFFER_SIZE
;
182 case OID_GEN_RECEIVE_BUFFER_SPACE
:
185 GenericULONG
= BUFFER_SIZE
;
189 case OID_GEN_TRANSMIT_BLOCK_SIZE
:
191 GenericULONG
= BUFFER_SIZE
;
195 case OID_GEN_RECEIVE_BLOCK_SIZE
:
197 GenericULONG
= BUFFER_SIZE
;
201 case OID_GEN_VENDOR_ID
:
203 UCHAR
*CharPtr
= (UCHAR
*)&GenericULONG
;
205 /* Read the first three bytes of the permanent MAC address */
206 NdisRawReadPortUchar(Adapter
->PortOffset
, CharPtr
);
207 NdisRawReadPortUchar(Adapter
->PortOffset
+ 1, CharPtr
+ 1);
208 NdisRawReadPortUchar(Adapter
->PortOffset
+ 2, CharPtr
+ 2);
212 case OID_GEN_VENDOR_DESCRIPTION
:
214 static UCHAR VendorDesc
[] = "ReactOS Team";
215 CopyFrom
= VendorDesc
;
216 CopySize
= sizeof(VendorDesc
);
220 case OID_GEN_VENDOR_DRIVER_VERSION
:
222 /* XXX implement me */
227 case OID_GEN_CURRENT_PACKET_FILTER
:
229 GenericULONG
= Adapter
->CurrentPacketFilter
;
233 case OID_GEN_DRIVER_VERSION
:
235 /* NDIS version used by the driver. */
236 static const USHORT DriverVersion
=
237 (NDIS_MINIPORT_MAJOR_VERSION
<< 8) + NDIS_MINIPORT_MINOR_VERSION
;
238 CopyFrom
= (PVOID
)&DriverVersion
;
239 CopySize
= sizeof(DriverVersion
);
243 case OID_GEN_MAXIMUM_TOTAL_SIZE
:
245 /* See comment in OID_GEN_MAXIMUM_FRAME_SIZE. */
250 case OID_GEN_PROTOCOL_OPTIONS
:
252 DPRINT("OID_GEN_PROTOCOL_OPTIONS.\n");
253 Status
= NDIS_STATUS_NOT_SUPPORTED
;
257 case OID_GEN_MAC_OPTIONS
:
259 GenericULONG
= NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
|
260 NDIS_MAC_OPTION_RECEIVE_SERIALIZED
|
261 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND
|
262 NDIS_MAC_OPTION_NO_LOOPBACK
;
266 case OID_GEN_MEDIA_CONNECT_STATUS
:
268 GenericULONG
= (ULONG
)NdisMediaStateConnected
; /* Adapter->MediaState */
272 case OID_GEN_MAXIMUM_SEND_PACKETS
:
278 case OID_802_3_CURRENT_ADDRESS
:
279 case OID_802_3_PERMANENT_ADDRESS
:
281 CopyFrom
= (PVOID
)&Adapter
->InitializationBlockVirt
->PADR
;
286 case OID_802_3_MAXIMUM_LIST_SIZE
:
288 GenericULONG
= MAX_MULTICAST_ADDRESSES
;
292 case OID_GEN_XMIT_OK
:
293 GenericULONG
= Adapter
->Statistics
.XmtGoodFrames
;
297 GenericULONG
= Adapter
->Statistics
.RcvGoodFrames
;
300 case OID_GEN_XMIT_ERROR
:
301 GenericULONG
= Adapter
->Statistics
.XmtRetryErrors
+
302 Adapter
->Statistics
.XmtLossesOfCarrier
+
303 Adapter
->Statistics
.XmtCollisions
+
304 Adapter
->Statistics
.XmtLateCollisions
+
305 Adapter
->Statistics
.XmtExcessiveDefferals
+
306 Adapter
->Statistics
.XmtBufferUnderflows
+
307 Adapter
->Statistics
.XmtBufferErrors
;
310 case OID_GEN_RCV_ERROR
:
311 GenericULONG
= Adapter
->Statistics
.RcvBufferErrors
+
312 Adapter
->Statistics
.RcvCrcErrors
+
313 Adapter
->Statistics
.RcvOverflowErrors
+
314 Adapter
->Statistics
.RcvFramingErrors
;
317 case OID_GEN_RCV_NO_BUFFER
:
318 GenericULONG
= Adapter
->Statistics
.RcvBufferErrors
+
319 Adapter
->Statistics
.RcvOverflowErrors
;
322 case OID_GEN_RCV_CRC_ERROR
:
323 GenericULONG
= Adapter
->Statistics
.RcvCrcErrors
;
326 case OID_802_3_RCV_ERROR_ALIGNMENT
:
327 GenericULONG
= Adapter
->Statistics
.RcvFramingErrors
;
330 case OID_802_3_XMIT_ONE_COLLISION
:
331 GenericULONG
= Adapter
->Statistics
.XmtOneRetry
;
334 case OID_802_3_XMIT_MORE_COLLISIONS
:
335 GenericULONG
= Adapter
->Statistics
.XmtMoreThanOneRetry
;
340 DPRINT1("Unknown OID\n");
341 Status
= NDIS_STATUS_NOT_SUPPORTED
;
346 if (Status
== NDIS_STATUS_SUCCESS
)
348 if (CopySize
> InformationBufferLength
)
350 *BytesNeeded
= CopySize
;
352 Status
= NDIS_STATUS_INVALID_LENGTH
;
356 NdisMoveMemory(InformationBuffer
, CopyFrom
, CopySize
);
357 *BytesWritten
= CopySize
;
358 *BytesNeeded
= CopySize
;
367 NdisReleaseSpinLock(&Adapter
->Lock
);
369 DPRINT("Leaving. Status is 0x%x\n", Status
);
376 MiniportSetInformation(
377 IN NDIS_HANDLE MiniportAdapterContext
,
379 IN PVOID InformationBuffer
,
380 IN ULONG InformationBufferLength
,
381 OUT PULONG BytesRead
,
382 OUT PULONG BytesNeeded
)
384 * FUNCTION: Set a miniport variable (OID)
386 * MiniportAdapterContext: context originally passed into NdisMSetAttributes
387 * Oid: the variable being set
388 * InformationBuffer: the data to set the variable to
389 * InformationBufferLength: number of bytes in InformationBuffer
390 * BytesRead: number of bytes read by us out of the buffer
391 * BytesNeeded: number of bytes required to satisfy the request if InformationBufferLength
394 * NDIS_STATUS_SUCCESS on all requests
396 * - Called by NDIS at DISPATCH_LEVEL
397 * - verify buffer space as mentioned in previous function notes
401 NDIS_STATUS Status
= NDIS_STATUS_SUCCESS
;
402 PADAPTER Adapter
= (PADAPTER
)MiniportAdapterContext
;
406 DPRINT("Called, OID 0x%x\n", Oid
);
408 NdisAcquireSpinLock(&Adapter
->Lock
);
412 case OID_GEN_CURRENT_PACKET_FILTER
:
415 if (InformationBufferLength
< sizeof(ULONG
))
418 *BytesNeeded
= sizeof(ULONG
);
419 Status
= NDIS_STATUS_INVALID_LENGTH
;
423 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
425 /* Check for properties the driver don't support */
427 (NDIS_PACKET_TYPE_ALL_FUNCTIONAL
|
428 NDIS_PACKET_TYPE_FUNCTIONAL
|
429 NDIS_PACKET_TYPE_GROUP
|
430 NDIS_PACKET_TYPE_MAC_FRAME
|
431 NDIS_PACKET_TYPE_SMT
|
432 NDIS_PACKET_TYPE_SOURCE_ROUTING
)
435 *BytesRead
= sizeof(ULONG
);
437 Status
= NDIS_STATUS_NOT_SUPPORTED
;
441 Adapter
->CurrentPacketFilter
= GenericULONG
;
443 /* FIXME: Set filter on hardware */
448 case OID_GEN_CURRENT_LOOKAHEAD
:
451 if (InformationBufferLength
< sizeof(ULONG
))
454 *BytesNeeded
= sizeof(ULONG
);
455 Status
= NDIS_STATUS_INVALID_LENGTH
;
459 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
461 if (GenericULONG
> 1500)
462 Status
= NDIS_STATUS_INVALID_DATA
;
464 Adapter
->CurrentLookaheadSize
= GenericULONG
;
469 case OID_802_3_MULTICAST_LIST
:
471 /* Verify length. Must be multiple of hardware address length */
472 if ((InformationBufferLength
% 6) != 0)
475 *BytesNeeded
= InformationBufferLength
+ (InformationBufferLength
% 6);
476 Status
= NDIS_STATUS_INVALID_LENGTH
;
480 ASSERT((InformationBufferLength
/ 6) <= MAX_MULTICAST_ADDRESSES
);
482 /* Set new multicast address list */
483 //NdisMoveMemory(Adapter->Addresses, InformationBuffer, InformationBufferLength);
485 /* Update hardware */
486 Status
= MiSetMulticast(Adapter
, InformationBuffer
, InformationBufferLength
/ 6);
493 DPRINT1("Invalid object ID (0x%X).\n", Oid
);
496 Status
= NDIS_STATUS_NOT_SUPPORTED
;
501 if (Status
== NDIS_STATUS_SUCCESS
)
503 *BytesRead
= InformationBufferLength
;
507 NdisReleaseSpinLock(&Adapter
->Lock
);
509 DPRINT("Leaving. Status (0x%X).\n", Status
);