Use standard debug macros
[reactos.git] / reactos / drivers / net / dd / pcnet / requests.c
1 /*
2 * ReactOS AMD PCNet Driver
3 *
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>
7 *
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.
12 *
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.
17 *
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.
21 *
22 * PROGRAMMERS:
23 * Vizzini (vizzini@plasmic.com),
24 * borrowed very heavily from the ReactOS ne2000 driver by
25 * Casper S. Hornstrup (chorns@users.sourceforge.net)
26 * REVISIONS:
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
33 * necessary.
34 */
35
36 #include <ndis.h>
37 #include "pcnethw.h"
38 #include "pcnet.h"
39
40 #define NDEBUG
41 #include <debug.h>
42
43 /* List of supported OIDs */
44 static ULONG MiniportOIDList[] =
45 {
46 OID_GEN_SUPPORTED_LIST,
47 OID_GEN_HARDWARE_STATUS,
48 OID_GEN_MEDIA_SUPPORTED,
49 OID_GEN_MEDIA_IN_USE,
50 OID_GEN_MAXIMUM_LOOKAHEAD,
51 OID_GEN_MAXIMUM_FRAME_SIZE,
52 OID_GEN_LINK_SPEED,
53 OID_GEN_TRANSMIT_BUFFER_SPACE,
54 OID_GEN_RECEIVE_BUFFER_SPACE,
55 OID_GEN_TRANSMIT_BLOCK_SIZE,
56 OID_GEN_RECEIVE_BLOCK_SIZE,
57 OID_GEN_VENDOR_ID,
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,
65 OID_GEN_MAC_OPTIONS,
66 OID_GEN_MEDIA_CONNECT_STATUS,
67 OID_GEN_MAXIMUM_SEND_PACKETS,
68 OID_GEN_XMIT_OK,
69 OID_GEN_RCV_OK,
70 OID_GEN_XMIT_ERROR,
71 OID_GEN_RCV_ERROR,
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
82 };
83
84 \f
85 NDIS_STATUS
86 STDCALL
87 MiniportQueryInformation(
88 IN NDIS_HANDLE MiniportAdapterContext,
89 IN NDIS_OID Oid,
90 IN PVOID InformationBuffer,
91 IN ULONG InformationBufferLength,
92 OUT PULONG BytesWritten,
93 OUT PULONG BytesNeeded)
94 /*
95 * FUNCTION: Query an OID from the driver
96 * ARGUMENTS:
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
103 * RETURNS:
104 * NDIS_STATUS_SUCCESS on all queries
105 * NOTES:
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
109 * TODO:
110 * - Update to verify input buffer & size and return insufficient buffer codes
111 */
112 {
113 NDIS_STATUS Status;
114 PVOID CopyFrom;
115 UINT CopySize;
116 ULONG GenericULONG;
117 PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
118
119 DPRINT("Called. OID 0x%x\n", Oid);
120
121 ASSERT(Adapter);
122
123 NdisAcquireSpinLock(&Adapter->Lock);
124
125 Status = NDIS_STATUS_SUCCESS;
126 CopyFrom = (PVOID)&GenericULONG;
127 CopySize = sizeof(ULONG);
128
129 switch (Oid)
130 {
131 case OID_GEN_SUPPORTED_LIST:
132 {
133 CopyFrom = (PVOID)&MiniportOIDList;
134 CopySize = sizeof(MiniportOIDList);
135 break;
136 }
137
138 case OID_GEN_HARDWARE_STATUS:
139 {
140 /* TODO: implement this... */
141 GenericULONG = (ULONG)NdisHardwareStatusReady;
142 break;
143 }
144
145 case OID_GEN_MEDIA_SUPPORTED:
146 case OID_GEN_MEDIA_IN_USE:
147 {
148 static const NDIS_MEDIUM Medium = NdisMedium802_3;
149 CopyFrom = (PVOID)&Medium;
150 CopySize = sizeof(NDIS_MEDIUM);
151 break;
152 }
153
154 case OID_GEN_CURRENT_LOOKAHEAD:
155 case OID_GEN_MAXIMUM_LOOKAHEAD:
156 {
157 GenericULONG = 1500;
158 break;
159 }
160
161 case OID_GEN_MAXIMUM_FRAME_SIZE:
162 {
163 /*
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.
167 */
168 GenericULONG = 1500;
169 break;
170 }
171
172 case OID_GEN_LINK_SPEED:
173 {
174 GenericULONG = 100000; /* 10Mbps */
175 break;
176 }
177
178 case OID_GEN_TRANSMIT_BUFFER_SPACE:
179 {
180 /* XXX fix me */
181 GenericULONG = BUFFER_SIZE;
182 break;
183 }
184
185 case OID_GEN_RECEIVE_BUFFER_SPACE:
186 {
187 /* XXX fix me */
188 GenericULONG = BUFFER_SIZE;
189 break;
190 }
191
192 case OID_GEN_TRANSMIT_BLOCK_SIZE:
193 {
194 GenericULONG = BUFFER_SIZE;
195 break;
196 }
197
198 case OID_GEN_RECEIVE_BLOCK_SIZE:
199 {
200 GenericULONG = BUFFER_SIZE;
201 break;
202 }
203
204 case OID_GEN_VENDOR_ID:
205 {
206 UCHAR *CharPtr = (UCHAR *)&GenericULONG;
207 GenericULONG = 0;
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);
212 break;
213 }
214
215 case OID_GEN_VENDOR_DESCRIPTION:
216 {
217 static UCHAR VendorDesc[] = "ReactOS Team";
218 CopyFrom = VendorDesc;
219 CopySize = sizeof(VendorDesc);
220 break;
221 }
222
223 case OID_GEN_VENDOR_DRIVER_VERSION:
224 {
225 /* XXX implement me */
226 GenericULONG = 1;
227 break;
228 }
229
230 case OID_GEN_CURRENT_PACKET_FILTER:
231 {
232 GenericULONG = Adapter->CurrentPacketFilter;
233 break;
234 }
235
236 case OID_GEN_DRIVER_VERSION:
237 {
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);
243 break;
244 }
245
246 case OID_GEN_MAXIMUM_TOTAL_SIZE:
247 {
248 /* See comment in OID_GEN_MAXIMUM_FRAME_SIZE. */
249 GenericULONG = 1514;
250 break;
251 }
252
253 case OID_GEN_PROTOCOL_OPTIONS:
254 {
255 DPRINT("OID_GEN_PROTOCOL_OPTIONS.\n");
256 Status = NDIS_STATUS_NOT_SUPPORTED;
257 break;
258 }
259
260 case OID_GEN_MAC_OPTIONS:
261 {
262 GenericULONG = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
263 NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
264 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND;
265 break;
266 }
267
268 case OID_GEN_MEDIA_CONNECT_STATUS:
269 {
270 GenericULONG = Adapter->MediaState;
271 break;
272 }
273
274 case OID_GEN_MAXIMUM_SEND_PACKETS:
275 {
276 GenericULONG = 1;
277 break;
278 }
279
280 case OID_802_3_CURRENT_ADDRESS:
281 case OID_802_3_PERMANENT_ADDRESS:
282 {
283 CopyFrom = (PVOID)&Adapter->InitializationBlockVirt->PADR;
284 CopySize = 6;
285 break;
286 }
287
288 case OID_802_3_MAXIMUM_LIST_SIZE:
289 {
290 GenericULONG = MAX_MULTICAST_ADDRESSES;
291 break;
292 }
293
294 case OID_GEN_XMIT_OK:
295 GenericULONG = Adapter->Statistics.XmtGoodFrames;
296 break;
297
298 case OID_GEN_RCV_OK:
299 GenericULONG = Adapter->Statistics.RcvGoodFrames;
300 break;
301
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;
310 break;
311
312 case OID_GEN_RCV_ERROR:
313 GenericULONG = Adapter->Statistics.RcvBufferErrors +
314 Adapter->Statistics.RcvCrcErrors +
315 Adapter->Statistics.RcvOverflowErrors +
316 Adapter->Statistics.RcvFramingErrors;
317 break;
318
319 case OID_GEN_RCV_NO_BUFFER:
320 GenericULONG = Adapter->Statistics.RcvBufferErrors +
321 Adapter->Statistics.RcvOverflowErrors;
322 break;
323
324 case OID_GEN_RCV_CRC_ERROR:
325 GenericULONG = Adapter->Statistics.RcvCrcErrors;
326 break;
327
328 case OID_802_3_RCV_ERROR_ALIGNMENT:
329 GenericULONG = Adapter->Statistics.RcvFramingErrors;
330 break;
331
332 case OID_802_3_XMIT_ONE_COLLISION:
333 GenericULONG = Adapter->Statistics.XmtOneRetry;
334 break;
335
336 case OID_802_3_XMIT_MORE_COLLISIONS:
337 GenericULONG = Adapter->Statistics.XmtMoreThanOneRetry;
338 break;
339
340 default:
341 {
342 DPRINT1("Unknown OID\n");
343 Status = NDIS_STATUS_NOT_SUPPORTED;
344 break;
345 }
346 }
347
348 if (Status == NDIS_STATUS_SUCCESS)
349 {
350 if (CopySize > InformationBufferLength)
351 {
352 *BytesNeeded = (CopySize - InformationBufferLength);
353 *BytesWritten = 0;
354 Status = NDIS_STATUS_BUFFER_TOO_SHORT;
355 }
356 else
357 {
358 NdisMoveMemory(InformationBuffer, CopyFrom, CopySize);
359 *BytesWritten = CopySize;
360 *BytesNeeded = CopySize;
361 }
362 }
363
364 NdisReleaseSpinLock(&Adapter->Lock);
365
366 DPRINT("Leaving. Status is 0x%x\n", Status);
367
368 return Status;
369 }
370
371 NDIS_STATUS
372 STDCALL
373 MiniportSetInformation(
374 IN NDIS_HANDLE MiniportAdapterContext,
375 IN NDIS_OID Oid,
376 IN PVOID InformationBuffer,
377 IN ULONG InformationBufferLength,
378 OUT PULONG BytesRead,
379 OUT PULONG BytesNeeded)
380 /*
381 * FUNCTION: Set a miniport variable (OID)
382 * ARGUMENTS:
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
389 * is insufficient
390 * RETURNS:
391 * NDIS_STATUS_SUCCESS on all requests
392 * NOTES:
393 * - Called by NDIS at PASSIVE_LEVEL
394 * - verify buffer space as mentioned in previous function notes
395 */
396 {
397 ULONG GenericULONG;
398 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
399 PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
400
401 ASSERT(Adapter);
402
403 DPRINT("Called, OID 0x%x\n", Oid);
404
405 NdisAcquireSpinLock(&Adapter->Lock);
406
407 switch (Oid)
408 {
409 case OID_GEN_CURRENT_PACKET_FILTER:
410 {
411 /* Verify length */
412 if (InformationBufferLength < sizeof(ULONG))
413 {
414 *BytesRead = 0;
415 *BytesNeeded = sizeof(ULONG) - InformationBufferLength;
416 Status = NDIS_STATUS_INVALID_LENGTH;
417 break;
418 }
419
420 NdisMoveMemory(&GenericULONG, InformationBuffer, sizeof(ULONG));
421
422 /* Check for properties the driver don't support */
423 if (GenericULONG &
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)
430 )
431 {
432 *BytesRead = 4;
433 *BytesNeeded = 0;
434 Status = NDIS_STATUS_NOT_SUPPORTED;
435 break;
436 }
437
438 Adapter->CurrentPacketFilter = GenericULONG;
439
440 /* FIXME: Set filter on hardware */
441
442 break;
443 }
444
445 case OID_GEN_CURRENT_LOOKAHEAD:
446 {
447 /* Verify length */
448 if (InformationBufferLength < sizeof(ULONG))
449 {
450 *BytesRead = 0;
451 *BytesNeeded = sizeof(ULONG) - InformationBufferLength;
452 Status = NDIS_STATUS_INVALID_LENGTH;
453 break;
454 }
455
456 NdisMoveMemory(&GenericULONG, InformationBuffer, sizeof(ULONG));
457
458 if (GenericULONG > 1500)
459 Status = NDIS_STATUS_INVALID_LENGTH;
460 else
461 Adapter->CurrentLookaheadSize = GenericULONG;
462
463 break;
464 }
465
466 case OID_802_3_MULTICAST_LIST:
467 {
468 /* Verify length. Must be multiple of hardware address length */
469 if ((InformationBufferLength % 6) != 0)
470 {
471 *BytesRead = 0;
472 *BytesNeeded = 0;
473 Status = NDIS_STATUS_INVALID_LENGTH;
474 break;
475 }
476
477 ASSERT((InformationBufferLength / 6) <= MAX_MULTICAST_ADDRESSES);
478
479 /* Set new multicast address list */
480 //NdisMoveMemory(Adapter->Addresses, InformationBuffer, InformationBufferLength);
481
482 /* Update hardware */
483 Status = MiSetMulticast(Adapter, InformationBuffer, InformationBufferLength / 6);
484
485 break;
486 }
487
488 default:
489 {
490 DPRINT1("Invalid object ID (0x%X).\n", Oid);
491 *BytesRead = 0;
492 *BytesNeeded = 0;
493 Status = NDIS_STATUS_NOT_SUPPORTED;
494 break;
495 }
496 }
497
498 if (Status == NDIS_STATUS_SUCCESS)
499 {
500 *BytesRead = InformationBufferLength;
501 *BytesNeeded = 0;
502 }
503
504 NdisReleaseSpinLock(&Adapter->Lock);
505
506 DPRINT("Leaving. Status (0x%X).\n", Status);
507
508 return Status;
509 }
510