win-pvdrivers

view xennet/xennet_oid.c @ 649:cbd4e4ae9527

Fix missing reg delete in uninstaller
author James Harper <james.harper@bendigoit.com.au>
date Mon Sep 07 13:26:25 2009 +1000 (2009-09-07)
parents d1754b0e1ead
children 93b98effc8e7
line source
1 /*
2 PV Net Driver for Windows Xen HVM Domains
3 Copyright (C) 2007 James Harper
4 Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
21 #include "xennet.h"
23 // Q = Query Mandatory, S = Set Mandatory
24 NDIS_OID supported_oids[] =
25 {
26 /* general OIDs */
27 OID_GEN_SUPPORTED_LIST, // Q
28 OID_GEN_HARDWARE_STATUS, // Q
29 OID_GEN_MEDIA_SUPPORTED, // Q
30 OID_GEN_MEDIA_IN_USE, // Q
31 OID_GEN_MAXIMUM_LOOKAHEAD, // Q
32 OID_GEN_MAXIMUM_FRAME_SIZE, // Q
33 OID_GEN_LINK_SPEED, // Q
34 OID_GEN_TRANSMIT_BUFFER_SPACE, // Q
35 OID_GEN_RECEIVE_BUFFER_SPACE, // Q
36 OID_GEN_TRANSMIT_BLOCK_SIZE, // Q
37 OID_GEN_RECEIVE_BLOCK_SIZE, // Q
38 OID_GEN_VENDOR_ID, // Q
39 OID_GEN_VENDOR_DESCRIPTION, // Q
40 OID_GEN_CURRENT_PACKET_FILTER, // QS
41 OID_GEN_CURRENT_LOOKAHEAD, // QS
42 OID_GEN_DRIVER_VERSION, // Q
43 OID_GEN_VENDOR_DRIVER_VERSION, // Q
44 OID_GEN_MAXIMUM_TOTAL_SIZE, // Q
45 OID_GEN_PROTOCOL_OPTIONS, // S
46 OID_GEN_MAC_OPTIONS, // Q
47 OID_GEN_MEDIA_CONNECT_STATUS, // Q
48 OID_GEN_MAXIMUM_SEND_PACKETS, // Q
49 /* stats */
50 OID_GEN_XMIT_OK, // Q
51 OID_GEN_RCV_OK, // Q
52 OID_GEN_XMIT_ERROR, // Q
53 OID_GEN_RCV_ERROR, // Q
54 OID_GEN_RCV_NO_BUFFER, // Q
55 /* media-specific OIDs */
56 OID_802_3_PERMANENT_ADDRESS,
57 OID_802_3_CURRENT_ADDRESS,
58 OID_802_3_MULTICAST_LIST,
59 OID_802_3_MAXIMUM_LIST_SIZE,
60 OID_802_3_RCV_ERROR_ALIGNMENT,
61 OID_802_3_XMIT_ONE_COLLISION,
62 OID_802_3_XMIT_MORE_COLLISIONS,
63 /* tcp offload */
64 OID_TCP_TASK_OFFLOAD,
65 /* power */
66 OID_PNP_CAPABILITIES,
67 OID_PNP_SET_POWER,
68 OID_PNP_QUERY_POWER,
69 };
71 /* return 4 or 8 depending on size of buffer */
72 #define HANDLE_STAT_RETURN \
73 {if (InformationBufferLength == 4) { \
74 len = 4; *BytesNeeded = 8; \
75 } else { \
76 len = 8; \
77 } }
79 NDIS_STATUS DDKAPI
80 XenNet_QueryInformation(
81 IN NDIS_HANDLE MiniportAdapterContext,
82 IN NDIS_OID Oid,
83 IN PVOID InformationBuffer,
84 IN ULONG InformationBufferLength,
85 OUT PULONG BytesWritten,
86 OUT PULONG BytesNeeded)
87 {
88 struct xennet_info *xi = MiniportAdapterContext;
89 UCHAR vendor_desc[] = XN_VENDOR_DESC;
90 ULONG64 temp_data;
91 PVOID data = &temp_data;
92 UINT len = 4;
93 BOOLEAN used_temp_buffer = TRUE;
94 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
95 PNDIS_TASK_OFFLOAD_HEADER ntoh;
96 PNDIS_TASK_OFFLOAD nto;
97 PNDIS_TASK_TCP_IP_CHECKSUM nttic;
98 PNDIS_TASK_TCP_LARGE_SEND nttls;
99 PNDIS_PNP_CAPABILITIES npc;
101 *BytesNeeded = 0;
102 *BytesWritten = 0;
104 // FUNCTION_ENTER()
106 switch(Oid)
107 {
108 case OID_GEN_SUPPORTED_LIST:
109 data = supported_oids;
110 len = sizeof(supported_oids);
111 break;
112 case OID_GEN_HARDWARE_STATUS:
113 if (!xi->connected)
114 {
115 temp_data = NdisHardwareStatusInitializing;
116 FUNCTION_MSG("NdisHardwareStatusInitializing\n");
117 }
118 else
119 {
120 temp_data = NdisHardwareStatusReady;
121 FUNCTION_MSG("NdisHardwareStatusReady\n");
122 }
123 break;
124 case OID_GEN_MEDIA_SUPPORTED:
125 temp_data = NdisMedium802_3;
126 break;
127 case OID_GEN_MEDIA_IN_USE:
128 temp_data = NdisMedium802_3;
129 break;
130 case OID_GEN_MAXIMUM_LOOKAHEAD:
131 temp_data = xi->config_mtu;
132 break;
133 case OID_GEN_MAXIMUM_FRAME_SIZE:
134 temp_data = xi->config_mtu;
135 break;
136 case OID_GEN_LINK_SPEED:
137 temp_data = 10000000; /* 1Gb */
138 break;
139 case OID_GEN_TRANSMIT_BUFFER_SPACE:
140 /* multiply this by some small number as we can queue additional packets */
141 temp_data = PAGE_SIZE * NET_TX_RING_SIZE * 4;
142 break;
143 case OID_GEN_RECEIVE_BUFFER_SPACE:
144 temp_data = PAGE_SIZE * NET_RX_RING_SIZE * 2;
145 break;
146 case OID_GEN_TRANSMIT_BLOCK_SIZE:
147 temp_data = PAGE_SIZE; //XN_MAX_PKT_SIZE;
148 break;
149 case OID_GEN_RECEIVE_BLOCK_SIZE:
150 temp_data = PAGE_SIZE; //XN_MAX_PKT_SIZE;
151 break;
152 case OID_GEN_VENDOR_ID:
153 temp_data = 0xFFFFFF; // Not guaranteed to be XENSOURCE_MAC_HDR;
154 break;
155 case OID_GEN_VENDOR_DESCRIPTION:
156 data = vendor_desc;
157 len = sizeof(vendor_desc);
158 break;
159 case OID_GEN_CURRENT_PACKET_FILTER:
160 temp_data = xi->packet_filter;
161 break;
162 case OID_GEN_CURRENT_LOOKAHEAD:
163 temp_data = xi->config_mtu;
164 break;
165 case OID_GEN_DRIVER_VERSION:
166 temp_data = (NDIS_MINIPORT_MAJOR_VERSION << 8) | NDIS_MINIPORT_MINOR_VERSION;
167 len = 2;
168 break;
169 case OID_GEN_VENDOR_DRIVER_VERSION:
170 temp_data = VENDOR_DRIVER_VERSION;
171 len = 4;
172 break;
173 case OID_GEN_MAXIMUM_TOTAL_SIZE:
174 temp_data = xi->config_mtu + XN_HDR_SIZE;
175 break;
176 case OID_GEN_MAC_OPTIONS:
177 temp_data = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
178 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
179 NDIS_MAC_OPTION_NO_LOOPBACK;
180 break;
181 case OID_GEN_MEDIA_CONNECT_STATUS:
182 if (xi->connected && !xi->inactive)
183 temp_data = NdisMediaStateConnected;
184 else
185 temp_data = NdisMediaStateDisconnected;
186 break;
187 case OID_GEN_MAXIMUM_SEND_PACKETS:
188 /* this is actually ignored for deserialised drivers like us */
189 temp_data = 0; //XN_MAX_SEND_PKTS;
190 break;
191 case OID_GEN_XMIT_OK:
192 temp_data = xi->stat_tx_ok;
193 HANDLE_STAT_RETURN;
194 break;
195 case OID_GEN_RCV_OK:
196 temp_data = xi->stat_rx_ok;
197 HANDLE_STAT_RETURN;
198 break;
199 case OID_GEN_XMIT_ERROR:
200 temp_data = xi->stat_tx_error;
201 HANDLE_STAT_RETURN;
202 break;
203 case OID_GEN_RCV_ERROR:
204 temp_data = xi->stat_rx_error;
205 HANDLE_STAT_RETURN;
206 break;
207 case OID_GEN_RCV_NO_BUFFER:
208 temp_data = xi->stat_rx_no_buffer;
209 HANDLE_STAT_RETURN;
210 break;
211 case OID_802_3_PERMANENT_ADDRESS:
212 data = xi->perm_mac_addr;
213 len = ETH_ALEN;
214 break;
215 case OID_802_3_CURRENT_ADDRESS:
216 data = xi->curr_mac_addr;
217 len = ETH_ALEN;
218 break;
219 case OID_802_3_RCV_ERROR_ALIGNMENT:
220 case OID_802_3_XMIT_ONE_COLLISION:
221 case OID_802_3_XMIT_MORE_COLLISIONS:
222 temp_data = 0;
223 HANDLE_STAT_RETURN;
224 break;
225 case OID_802_3_MULTICAST_LIST:
226 data = xi->multicast_list;
227 len = xi->multicast_list_size * 6;
228 break;
229 case OID_802_3_MAXIMUM_LIST_SIZE:
230 temp_data = MULTICAST_LIST_MAX_SIZE; /* no mcast support, but to return 0 is an error */
231 break;
232 case OID_TCP_TASK_OFFLOAD:
233 KdPrint(("Get OID_TCP_TASK_OFFLOAD\n"));
234 /* it's times like this that C really sucks */
236 len = sizeof(NDIS_TASK_OFFLOAD_HEADER);
238 if (xi->config_csum)
239 {
240 len += FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
241 + sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
242 }
244 if (xi->config_gso)
245 {
246 len += FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
247 + sizeof(NDIS_TASK_TCP_LARGE_SEND);
248 }
250 //len += 1024;
252 if (len > InformationBufferLength)
253 {
254 break;
255 }
257 ntoh = (PNDIS_TASK_OFFLOAD_HEADER)InformationBuffer;
258 if (ntoh->Version != NDIS_TASK_OFFLOAD_VERSION
259 || ntoh->Size != sizeof(*ntoh)
260 || !(
261 ntoh->EncapsulationFormat.Encapsulation == IEEE_802_3_Encapsulation
262 || (ntoh->EncapsulationFormat.Encapsulation == UNSPECIFIED_Encapsulation
263 && ntoh->EncapsulationFormat.EncapsulationHeaderSize == XN_HDR_SIZE)))
264 {
265 status = NDIS_STATUS_NOT_SUPPORTED;
266 break;
267 }
268 ntoh->OffsetFirstTask = 0;
269 nto = NULL;
271 if (xi->config_csum)
272 {
273 if (ntoh->OffsetFirstTask == 0)
274 {
275 ntoh->OffsetFirstTask = ntoh->Size;
276 nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(ntoh) + ntoh->OffsetFirstTask);
277 }
278 else
279 {
280 nto->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
281 + nto->TaskBufferLength;
282 nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(nto) + nto->OffsetNextTask);
283 }
284 /* fill in first nto */
285 nto->Version = NDIS_TASK_OFFLOAD_VERSION;
286 nto->Size = sizeof(NDIS_TASK_OFFLOAD);
287 nto->Task = TcpIpChecksumNdisTask;
288 nto->TaskBufferLength = sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
290 KdPrint(("config_csum enabled\n"));
291 KdPrint(("nto = %p\n", nto));
292 KdPrint(("nto->Size = %d\n", nto->Size));
293 KdPrint(("nto->TaskBufferLength = %d\n", nto->TaskBufferLength));
295 /* fill in checksum offload struct */
296 nttic = (PNDIS_TASK_TCP_IP_CHECKSUM)nto->TaskBuffer;
297 nttic->V4Transmit.IpChecksum = 0;
298 nttic->V4Transmit.IpOptionsSupported = 0;
299 nttic->V4Transmit.TcpChecksum = 1;
300 nttic->V4Transmit.TcpOptionsSupported = 1;
301 nttic->V4Transmit.UdpChecksum = 1;
302 nttic->V4Receive.IpChecksum = 0;
303 nttic->V4Receive.IpOptionsSupported = 0;
304 nttic->V4Receive.TcpChecksum = 1;
305 nttic->V4Receive.TcpOptionsSupported = 1;
306 nttic->V4Receive.UdpChecksum = 1;
307 nttic->V6Transmit.IpOptionsSupported = 0;
308 nttic->V6Transmit.TcpOptionsSupported = 0;
309 nttic->V6Transmit.TcpChecksum = 0;
310 nttic->V6Transmit.UdpChecksum = 0;
311 nttic->V6Receive.IpOptionsSupported = 0;
312 nttic->V6Receive.TcpOptionsSupported = 0;
313 nttic->V6Receive.TcpChecksum = 0;
314 nttic->V6Receive.UdpChecksum = 0;
315 }
316 if (xi->config_gso)
317 {
318 if (ntoh->OffsetFirstTask == 0)
319 {
320 ntoh->OffsetFirstTask = ntoh->Size;
321 nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(ntoh) + ntoh->OffsetFirstTask);
322 }
323 else
324 {
325 nto->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
326 + nto->TaskBufferLength;
327 nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(nto) + nto->OffsetNextTask);
328 }
330 /* fill in second nto */
331 nto->Version = NDIS_TASK_OFFLOAD_VERSION;
332 nto->Size = sizeof(NDIS_TASK_OFFLOAD);
333 nto->Task = TcpLargeSendNdisTask;
334 nto->TaskBufferLength = sizeof(NDIS_TASK_TCP_LARGE_SEND);
336 KdPrint(("config_gso enabled\n"));
337 KdPrint(("nto = %p\n", nto));
338 KdPrint(("nto->Size = %d\n", nto->Size));
339 KdPrint(("nto->TaskBufferLength = %d\n", nto->TaskBufferLength));
341 /* fill in large send struct */
342 nttls = (PNDIS_TASK_TCP_LARGE_SEND)nto->TaskBuffer;
343 nttls->Version = 0;
344 nttls->MaxOffLoadSize = xi->config_gso;
345 nttls->MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
346 nttls->TcpOptions = FALSE; /* linux can't handle this */
347 nttls->IpOptions = FALSE; /* linux can't handle this */
348 KdPrint(("&(nttls->IpOptions) = %p\n", &(nttls->IpOptions)));
349 }
351 if (nto)
352 nto->OffsetNextTask = 0; /* last one */
354 used_temp_buffer = FALSE;
355 break;
356 case OID_IP4_OFFLOAD_STATS:
357 case OID_IP6_OFFLOAD_STATS:
358 /* these are called often so just ignore then quietly */
359 status = NDIS_STATUS_NOT_SUPPORTED;
360 break;
362 case OID_PNP_CAPABILITIES:
363 KdPrint(("Get OID_PNP_CAPABILITIES\n"));
364 len = sizeof(NDIS_PNP_CAPABILITIES);
365 if (len > InformationBufferLength)
366 break;
367 npc = (PNDIS_PNP_CAPABILITIES)InformationBuffer;
368 npc->Flags = 0;
369 npc->WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
370 npc->WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateUnspecified;
371 npc->WakeUpCapabilities.MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
372 used_temp_buffer = FALSE;
373 break;
374 case OID_PNP_QUERY_POWER:
375 KdPrint(("Get OID_PNP_CAPABILITIES\n"));
376 used_temp_buffer = FALSE;
377 break;
379 default:
380 KdPrint(("Get Unknown OID 0x%x\n", Oid));
381 status = NDIS_STATUS_NOT_SUPPORTED;
382 }
384 if (!NT_SUCCESS(status))
385 {
386 // FUNCTION_ERROR_EXIT();
387 return status;
388 }
390 if (len > InformationBufferLength)
391 {
392 *BytesNeeded = len;
393 FUNCTION_MSG("(BUFFER_TOO_SHORT %d > %d)\n", len, InformationBufferLength);
394 return NDIS_STATUS_BUFFER_TOO_SHORT;
395 }
397 *BytesWritten = len;
398 if (len && used_temp_buffer)
399 {
400 NdisMoveMemory((PUCHAR)InformationBuffer, data, len);
401 }
403 //KdPrint(("Got OID 0x%x\n", Oid));
404 // KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
406 return status;
407 }
409 NDIS_STATUS DDKAPI
410 XenNet_SetInformation(
411 IN NDIS_HANDLE MiniportAdapterContext,
412 IN NDIS_OID Oid,
413 IN PVOID InformationBuffer,
414 IN ULONG InformationBufferLength,
415 OUT PULONG BytesRead,
416 OUT PULONG BytesNeeded
417 )
418 {
419 NTSTATUS status;
420 ULONG i;
421 struct xennet_info *xi = MiniportAdapterContext;
422 PULONG64 data = InformationBuffer;
423 PNDIS_TASK_OFFLOAD_HEADER ntoh;
424 PNDIS_TASK_OFFLOAD nto;
425 PNDIS_TASK_TCP_IP_CHECKSUM nttic = NULL;
426 PNDIS_TASK_TCP_LARGE_SEND nttls = NULL;
427 UCHAR *multicast_list;
428 int offset;
430 //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
432 UNREFERENCED_PARAMETER(MiniportAdapterContext);
433 UNREFERENCED_PARAMETER(InformationBufferLength);
434 UNREFERENCED_PARAMETER(BytesRead);
435 UNREFERENCED_PARAMETER(BytesNeeded);
437 switch(Oid)
438 {
439 case OID_GEN_SUPPORTED_LIST:
440 status = NDIS_STATUS_NOT_SUPPORTED;
441 KdPrint(("Unsupported set OID_GEN_SUPPORTED_LIST\n"));
442 break;
443 case OID_GEN_HARDWARE_STATUS:
444 status = NDIS_STATUS_NOT_SUPPORTED;
445 KdPrint(("Unsupported set OID_GEN_HARDWARE_STATUS\n"));
446 break;
447 case OID_GEN_MEDIA_SUPPORTED:
448 status = NDIS_STATUS_NOT_SUPPORTED;
449 KdPrint(("Unsupported set OID_GEN_MEDIA_SUPPORTED\n"));
450 break;
451 case OID_GEN_MEDIA_IN_USE:
452 status = NDIS_STATUS_NOT_SUPPORTED;
453 KdPrint(("Unsupported set OID_GEN_MEDIA_IN_USE\n"));
454 break;
455 case OID_GEN_MAXIMUM_LOOKAHEAD:
456 status = NDIS_STATUS_NOT_SUPPORTED;
457 KdPrint(("Unsupported set OID_GEN_MAXIMUM_LOOKAHEAD\n"));
458 break;
459 case OID_GEN_MAXIMUM_FRAME_SIZE:
460 status = NDIS_STATUS_NOT_SUPPORTED;
461 KdPrint(("Unsupported set OID_GEN_MAXIMUM_FRAME_SIZE\n"));
462 break;
463 case OID_GEN_LINK_SPEED:
464 status = NDIS_STATUS_NOT_SUPPORTED;
465 KdPrint(("Unsupported set OID_GEN_LINK_SPEED\n"));
466 break;
467 case OID_GEN_TRANSMIT_BUFFER_SPACE:
468 status = NDIS_STATUS_NOT_SUPPORTED;
469 KdPrint(("Unsupported set OID_GEN_TRANSMIT_BUFFER_SPACE\n"));
470 break;
471 case OID_GEN_RECEIVE_BUFFER_SPACE:
472 status = NDIS_STATUS_NOT_SUPPORTED;
473 KdPrint(("Unsupported set OID_GEN_RECEIVE_BUFFER_SPACE\n"));
474 break;
475 case OID_GEN_TRANSMIT_BLOCK_SIZE:
476 status = NDIS_STATUS_NOT_SUPPORTED;
477 KdPrint(("Unsupported set OID_GEN_TRANSMIT_BLOCK_SIZE\n"));
478 break;
479 case OID_GEN_RECEIVE_BLOCK_SIZE:
480 status = NDIS_STATUS_NOT_SUPPORTED;
481 KdPrint(("Unsupported set OID_GEN_RECEIVE_BLOCK_SIZE\n"));
482 break;
483 case OID_GEN_VENDOR_ID:
484 status = NDIS_STATUS_NOT_SUPPORTED;
485 KdPrint(("Unsupported set OID_GEN_VENDOR_ID\n"));
486 break;
487 case OID_GEN_VENDOR_DESCRIPTION:
488 status = NDIS_STATUS_NOT_SUPPORTED;
489 KdPrint(("Unsupported set OID_GEN_VENDOR_DESCRIPTION\n"));
490 break;
491 case OID_GEN_CURRENT_PACKET_FILTER:
492 KdPrint(("Set OID_GEN_CURRENT_PACKET_FILTER\n"));
493 if (*(ULONG *)data & NDIS_PACKET_TYPE_DIRECTED)
494 KdPrint((" NDIS_PACKET_TYPE_DIRECTED\n"));
495 if (*(ULONG *)data & NDIS_PACKET_TYPE_MULTICAST)
496 KdPrint((" NDIS_PACKET_TYPE_MULTICAST\n"));
497 if (*(ULONG *)data & NDIS_PACKET_TYPE_ALL_MULTICAST)
498 KdPrint((" NDIS_PACKET_TYPE_ALL_MULTICAST\n"));
499 if (*(ULONG *)data & NDIS_PACKET_TYPE_BROADCAST)
500 KdPrint((" NDIS_PACKET_TYPE_BROADCAST\n"));
501 if (*(ULONG *)data & NDIS_PACKET_TYPE_PROMISCUOUS)
502 KdPrint((" NDIS_PACKET_TYPE_PROMISCUOUS\n"));
503 if (*(ULONG *)data & NDIS_PACKET_TYPE_ALL_FUNCTIONAL)
504 KdPrint((" NDIS_PACKET_TYPE_ALL_FUNCTIONAL (not supported)\n"));
505 if (*(ULONG *)data & NDIS_PACKET_TYPE_ALL_LOCAL)
506 KdPrint((" NDIS_PACKET_TYPE_ALL_LOCAL (not supported)\n"));
507 if (*(ULONG *)data & NDIS_PACKET_TYPE_FUNCTIONAL)
508 KdPrint((" NDIS_PACKET_TYPE_FUNCTIONAL (not supported)\n"));
509 if (*(ULONG *)data & NDIS_PACKET_TYPE_GROUP)
510 KdPrint((" NDIS_PACKET_TYPE_GROUP (not supported)\n"));
511 if (*(ULONG *)data & ~SUPPORTED_PACKET_FILTERS)
512 {
513 status = NDIS_STATUS_NOT_SUPPORTED;
514 KdPrint((" returning NDIS_STATUS_NOT_SUPPORTED\n"));
515 break;
516 }
517 xi->packet_filter = *(ULONG *)data;
518 status = NDIS_STATUS_SUCCESS;
519 break;
520 case OID_GEN_CURRENT_LOOKAHEAD:
521 KdPrint(("Set OID_GEN_CURRENT_LOOKAHEAD %d\n", *(int *)data));
522 // TODO: We should do this...
523 status = NDIS_STATUS_SUCCESS;
524 break;
525 case OID_GEN_DRIVER_VERSION:
526 status = NDIS_STATUS_NOT_SUPPORTED;
527 KdPrint(("Unsupported set OID_GEN_DRIVER_VERSION\n"));
528 break;
529 case OID_GEN_MAXIMUM_TOTAL_SIZE:
530 status = NDIS_STATUS_NOT_SUPPORTED;
531 KdPrint(("Unsupported set OID_GEN_MAXIMUM_TOTAL_SIZE\n"));
532 break;
533 case OID_GEN_PROTOCOL_OPTIONS:
534 KdPrint(("Unsupported set OID_GEN_PROTOCOL_OPTIONS\n"));
535 // TODO - actually do this...
536 status = NDIS_STATUS_SUCCESS;
537 break;
538 case OID_GEN_MAC_OPTIONS:
539 status = NDIS_STATUS_NOT_SUPPORTED;
540 KdPrint(("Unsupported set OID_GEN_MAC_OPTIONS\n"));
541 break;
542 case OID_GEN_MEDIA_CONNECT_STATUS:
543 status = NDIS_STATUS_NOT_SUPPORTED;
544 KdPrint(("Unsupported set OID_GEN_MEDIA_CONNECT_STATUS\n"));
545 break;
546 case OID_GEN_MAXIMUM_SEND_PACKETS:
547 status = NDIS_STATUS_NOT_SUPPORTED;
548 KdPrint(("Unsupported set OID_GEN_MAXIMUM_SEND_PACKETS\n"));
549 break;
550 case OID_GEN_XMIT_OK:
551 status = NDIS_STATUS_NOT_SUPPORTED;
552 KdPrint(("Unsupported set OID_GEN_XMIT_OK\n"));
553 break;
554 case OID_GEN_RCV_OK:
555 status = NDIS_STATUS_NOT_SUPPORTED;
556 KdPrint(("Unsupported set OID_GEN_RCV_OK\n"));
557 break;
558 case OID_GEN_XMIT_ERROR:
559 status = NDIS_STATUS_NOT_SUPPORTED;
560 KdPrint(("Unsupported set OID_GEN_XMIT_ERROR\n"));
561 break;
562 case OID_GEN_RCV_ERROR:
563 status = NDIS_STATUS_NOT_SUPPORTED;
564 KdPrint(("Unsupported set OID_GEN_RCV_ERROR\n"));
565 break;
566 case OID_GEN_RCV_NO_BUFFER:
567 status = NDIS_STATUS_NOT_SUPPORTED;
568 KdPrint(("Unsupported set OID_GEN_RCV_NO_BUFFER\n"));
569 break;
570 case OID_802_3_PERMANENT_ADDRESS:
571 status = NDIS_STATUS_NOT_SUPPORTED;
572 KdPrint(("Unsupported set OID_802_3_PERMANENT_ADDRESS\n"));
573 break;
574 case OID_802_3_CURRENT_ADDRESS:
575 status = NDIS_STATUS_NOT_SUPPORTED;
576 KdPrint(("Unsupported set OID_802_3_CURRENT_ADDRESS\n"));
577 break;
578 case OID_802_3_MULTICAST_LIST:
579 KdPrint((" Set OID_802_3_MULTICAST_LIST\n"));
580 KdPrint((" Length = %d\n", InformationBufferLength));
581 KdPrint((" Entries = %d\n", InformationBufferLength / 6));
582 if (InformationBufferLength > MULTICAST_LIST_MAX_SIZE * 6)
583 {
584 status = NDIS_STATUS_MULTICAST_FULL;
585 break;
586 }
588 if (InformationBufferLength % 6 != 0)
589 {
590 status = NDIS_STATUS_MULTICAST_FULL;
591 break;
592 }
593 multicast_list = InformationBuffer;
594 for (i = 0; i < InformationBufferLength / 6; i++)
595 {
596 if (!(multicast_list[i * 6 + 0] & 0x01))
597 {
598 KdPrint((" Address %d (%02x:%02x:%02x:%02x:%02x:%02x) is not a multicast address\n", i,
599 (ULONG)multicast_list[i * 6 + 0], (ULONG)multicast_list[i * 6 + 1],
600 (ULONG)multicast_list[i * 6 + 2], (ULONG)multicast_list[i * 6 + 3],
601 (ULONG)multicast_list[i * 6 + 4], (ULONG)multicast_list[i * 6 + 5]));
602 status = NDIS_STATUS_MULTICAST_FULL;
603 break;
604 }
605 }
606 memcpy(xi->multicast_list, InformationBuffer, InformationBufferLength);
607 xi->multicast_list_size = InformationBufferLength / 6;
608 status = NDIS_STATUS_SUCCESS;
609 break;
610 case OID_802_3_MAXIMUM_LIST_SIZE:
611 status = NDIS_STATUS_NOT_SUPPORTED;
612 KdPrint(("Unsupported set OID_802_3_MAXIMUM_LIST_SIZE\n"));
613 break;
614 case OID_TCP_TASK_OFFLOAD:
615 status = NDIS_STATUS_SUCCESS;
616 KdPrint(("Set OID_TCP_TASK_OFFLOAD\n"));
617 // we should disable everything here, then enable what has been set
618 ntoh = (PNDIS_TASK_OFFLOAD_HEADER)InformationBuffer;
619 if (ntoh->Version != NDIS_TASK_OFFLOAD_VERSION)
620 {
621 KdPrint(("Invalid version (%d passed but must be %d)\n", ntoh->Version, NDIS_TASK_OFFLOAD_VERSION));
622 status = NDIS_STATUS_INVALID_DATA;
623 break;
624 }
625 if (ntoh->Version != NDIS_TASK_OFFLOAD_VERSION || ntoh->Size != sizeof(NDIS_TASK_OFFLOAD_HEADER))
626 {
627 KdPrint(("Invalid size (%d passed but must be %d)\n", ntoh->Size, sizeof(NDIS_TASK_OFFLOAD_HEADER)));
628 status = NDIS_STATUS_INVALID_DATA;
629 break;
630 }
631 *BytesRead = sizeof(NDIS_TASK_OFFLOAD_HEADER);
632 offset = ntoh->OffsetFirstTask;
633 nto = (PNDIS_TASK_OFFLOAD)ntoh; // not really, just to get the first offset right
634 while (offset != 0)
635 {
636 *BytesRead += FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer);
637 nto = (PNDIS_TASK_OFFLOAD)(((PUCHAR)nto) + offset);
638 switch (nto->Task)
639 {
640 case TcpIpChecksumNdisTask:
641 *BytesRead += sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
642 nttic = (PNDIS_TASK_TCP_IP_CHECKSUM)nto->TaskBuffer;
643 KdPrint(("TcpIpChecksumNdisTask\n"));
644 KdPrint((" V4Transmit.IpOptionsSupported = %d\n", nttic->V4Transmit.IpOptionsSupported));
645 KdPrint((" V4Transmit.TcpOptionsSupported = %d\n", nttic->V4Transmit.TcpOptionsSupported));
646 KdPrint((" V4Transmit.TcpChecksum = %d\n", nttic->V4Transmit.TcpChecksum));
647 KdPrint((" V4Transmit.UdpChecksum = %d\n", nttic->V4Transmit.UdpChecksum));
648 KdPrint((" V4Transmit.IpChecksum = %d\n", nttic->V4Transmit.IpChecksum));
649 KdPrint((" V4Receive.IpOptionsSupported = %d\n", nttic->V4Receive.IpOptionsSupported));
650 KdPrint((" V4Receive.TcpOptionsSupported = %d\n", nttic->V4Receive.TcpOptionsSupported));
651 KdPrint((" V4Receive.TcpChecksum = %d\n", nttic->V4Receive.TcpChecksum));
652 KdPrint((" V4Receive.UdpChecksum = %d\n", nttic->V4Receive.UdpChecksum));
653 KdPrint((" V4Receive.IpChecksum = %d\n", nttic->V4Receive.IpChecksum));
654 KdPrint((" V6Transmit.IpOptionsSupported = %d\n", nttic->V6Transmit.IpOptionsSupported));
655 KdPrint((" V6Transmit.TcpOptionsSupported = %d\n", nttic->V6Transmit.TcpOptionsSupported));
656 KdPrint((" V6Transmit.TcpChecksum = %d\n", nttic->V6Transmit.TcpChecksum));
657 KdPrint((" V6Transmit.UdpChecksum = %d\n", nttic->V6Transmit.UdpChecksum));
658 KdPrint((" V6Receive.IpOptionsSupported = %d\n", nttic->V6Receive.IpOptionsSupported));
659 KdPrint((" V6Receive.TcpOptionsSupported = %d\n", nttic->V6Receive.TcpOptionsSupported));
660 KdPrint((" V6Receive.TcpChecksum = %d\n", nttic->V6Receive.TcpChecksum));
661 KdPrint((" V6Receive.UdpChecksum = %d\n", nttic->V6Receive.UdpChecksum));
662 /* check for stuff we outright don't support */
663 if (nttic->V6Transmit.IpOptionsSupported ||
664 nttic->V6Transmit.TcpOptionsSupported ||
665 nttic->V6Transmit.TcpChecksum ||
666 nttic->V6Transmit.UdpChecksum ||
667 nttic->V6Receive.IpOptionsSupported ||
668 nttic->V6Receive.TcpOptionsSupported ||
669 nttic->V6Receive.TcpChecksum ||
670 nttic->V6Receive.UdpChecksum)
671 {
672 KdPrint(("IPv6 offload not supported\n"));
673 status = NDIS_STATUS_INVALID_DATA;
674 nttic = NULL;
675 break;
676 }
677 if (nttic->V4Transmit.IpOptionsSupported ||
678 nttic->V4Transmit.IpChecksum)
679 {
680 KdPrint(("IPv4 IP Transmit offload not supported\n"));
681 status = NDIS_STATUS_INVALID_DATA;
682 nttic = NULL;
683 break;
684 }
685 if (nttic->V4Receive.IpOptionsSupported &&
686 !nttic->V4Receive.IpChecksum)
687 {
688 KdPrint(("Invalid combination\n"));
689 status = NDIS_STATUS_INVALID_DATA;
690 nttic = NULL;
691 break;
692 }
693 if (nttic->V4Transmit.TcpOptionsSupported &&
694 !nttic->V4Transmit.TcpChecksum)
695 {
696 KdPrint(("Invalid combination\n"));
697 status = NDIS_STATUS_INVALID_DATA;
698 nttic = NULL;
699 break;
700 }
701 if (nttic->V4Receive.TcpOptionsSupported &&
702 !nttic->V4Receive.TcpChecksum)
703 {
704 KdPrint(("Invalid combination\n"));
705 status = NDIS_STATUS_INVALID_DATA;
706 nttic = NULL;
707 break;
708 }
709 break;
710 case TcpLargeSendNdisTask:
711 *BytesRead += sizeof(NDIS_TASK_TCP_LARGE_SEND);
712 KdPrint(("TcpLargeSendNdisTask\n"));
713 nttls = (PNDIS_TASK_TCP_LARGE_SEND)nto->TaskBuffer;
714 KdPrint((" MaxOffLoadSize = %d\n", nttls->MaxOffLoadSize));
715 KdPrint((" MinSegmentCount = %d\n", nttls->MinSegmentCount));
716 KdPrint((" TcpOptions = %d\n", nttls->TcpOptions));
717 KdPrint((" IpOptions = %d\n", nttls->IpOptions));
718 if (nttls->MinSegmentCount != MIN_LARGE_SEND_SEGMENTS)
719 {
720 KdPrint((" MinSegmentCount should be %d\n", MIN_LARGE_SEND_SEGMENTS));
721 status = NDIS_STATUS_INVALID_DATA;
722 nttls = NULL;
723 break;
724 }
725 if (nttls->IpOptions)
726 {
727 KdPrint((" IpOptions not supported\n"));
728 status = NDIS_STATUS_INVALID_DATA;
729 nttls = NULL;
730 break;
731 }
732 if (nttls->TcpOptions)
733 {
734 KdPrint((" TcpOptions not supported\n"));
735 status = NDIS_STATUS_INVALID_DATA;
736 nttls = NULL;
737 break;
738 }
739 break;
740 default:
741 KdPrint((" Unknown Task %d\n", nto->Task));
742 }
743 offset = nto->OffsetNextTask;
744 }
745 if (nttic != NULL)
746 xi->setting_csum = *nttic;
747 else
748 {
749 RtlZeroMemory(&xi->setting_csum, sizeof(NDIS_TASK_TCP_IP_CHECKSUM));
750 KdPrint((" csum offload disabled\n", nto->Task));
751 }
752 if (nttls != NULL)
753 xi->setting_max_offload = nttls->MaxOffLoadSize;
754 else
755 {
756 xi->setting_max_offload = 0;
757 KdPrint((" LSO disabled\n", nto->Task));
758 }
759 break;
760 case OID_PNP_SET_POWER:
761 KdPrint((" Set OID_PNP_SET_POWER\n"));
762 switch (*(PNDIS_DEVICE_POWER_STATE )InformationBuffer)
763 {
764 case NdisDeviceStateD0:
765 KdPrint((" NdisDeviceStateD0\n"));
766 break;
767 case NdisDeviceStateD1:
768 KdPrint((" NdisDeviceStateD1\n"));
769 break;
770 case NdisDeviceStateD2:
771 KdPrint((" NdisDeviceStateD2\n"));
772 break;
773 case NdisDeviceStateD3:
774 KdPrint((" NdisDeviceStateD3\n"));
775 break;
776 default:
777 KdPrint((" NdisDeviceState??\n"));
778 break;
779 }
780 status = NDIS_STATUS_SUCCESS;
781 break;
782 default:
783 KdPrint(("Set Unknown OID 0x%x\n", Oid));
784 status = NDIS_STATUS_NOT_SUPPORTED;
785 break;
786 }
787 //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
788 return status;
789 }