win-pvdrivers

view xennet/xennet_oid.c @ 222:d37e4b226919

Almost working - rx offload packet splitting is working but not yet calculating checksums correctly. There may still be an occasional crash on init too from xennet_oid...
author James Harper <james.harper@bendigoit.com.au>
date Tue Mar 25 08:24:41 2008 +1100 (2008-03-25)
parents d076e1ed8071
children 0e71aec16493
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_MAXIMUM_TOTAL_SIZE, // Q
44 OID_GEN_PROTOCOL_OPTIONS, // S
45 OID_GEN_MAC_OPTIONS, // Q
46 OID_GEN_MEDIA_CONNECT_STATUS, // Q
47 OID_GEN_MAXIMUM_SEND_PACKETS, // Q
48 /* stats */
49 OID_GEN_XMIT_OK, // Q
50 OID_GEN_RCV_OK, // Q
51 OID_GEN_XMIT_ERROR, // Q
52 OID_GEN_RCV_ERROR, // Q
53 OID_GEN_RCV_NO_BUFFER, // Q
54 /* media-specific OIDs */
55 OID_802_3_PERMANENT_ADDRESS,
56 OID_802_3_CURRENT_ADDRESS,
57 OID_802_3_MULTICAST_LIST,
58 OID_802_3_MAXIMUM_LIST_SIZE,
59 /* tcp offload */
60 OID_TCP_TASK_OFFLOAD,
61 };
63 /* return 4 or 8 depending on size of buffer */
64 #define HANDLE_STAT_RETURN \
65 {if (InformationBufferLength == 4) { \
66 len = 4; *BytesNeeded = 8; \
67 } else { \
68 len = 8; \
69 } }
71 NDIS_STATUS
72 XenNet_QueryInformation(
73 IN NDIS_HANDLE MiniportAdapterContext,
74 IN NDIS_OID Oid,
75 IN PVOID InformationBuffer,
76 IN ULONG InformationBufferLength,
77 OUT PULONG BytesWritten,
78 OUT PULONG BytesNeeded)
79 {
80 struct xennet_info *xi = MiniportAdapterContext;
81 UCHAR vendor_desc[] = XN_VENDOR_DESC;
82 ULONG64 temp_data;
83 PVOID data = &temp_data;
84 UINT len = 4;
85 BOOLEAN used_temp_buffer = TRUE;
86 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
87 PNDIS_TASK_OFFLOAD_HEADER ntoh;
88 PNDIS_TASK_OFFLOAD nto;
89 PNDIS_TASK_TCP_IP_CHECKSUM nttic;
90 PNDIS_TASK_TCP_LARGE_SEND nttls;
92 // KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
94 switch(Oid)
95 {
96 case OID_GEN_SUPPORTED_LIST:
97 data = supported_oids;
98 len = sizeof(supported_oids);
99 break;
100 case OID_GEN_HARDWARE_STATUS:
101 if (!xi->connected)
102 temp_data = NdisHardwareStatusInitializing;
103 else
104 temp_data = NdisHardwareStatusReady;
105 break;
106 case OID_GEN_MEDIA_SUPPORTED:
107 temp_data = NdisMedium802_3;
108 break;
109 case OID_GEN_MEDIA_IN_USE:
110 temp_data = NdisMedium802_3;
111 break;
112 case OID_GEN_MAXIMUM_LOOKAHEAD:
113 temp_data = XN_DATA_SIZE;
114 break;
115 case OID_GEN_MAXIMUM_FRAME_SIZE:
116 // According to the specs, OID_GEN_MAXIMUM_FRAME_SIZE does not include the header, so
117 // it is XN_DATA_SIZE not XN_MAX_PKT_SIZE
118 temp_data = XN_DATA_SIZE;
119 break;
120 case OID_GEN_LINK_SPEED:
121 temp_data = 10000000; /* 1Gb */
122 break;
123 case OID_GEN_TRANSMIT_BUFFER_SPACE:
124 /* pkts times sizeof ring, maybe? */
125 // temp_data = XN_MAX_PKT_SIZE * NET_TX_RING_SIZE;
126 temp_data = PAGE_SIZE * NET_TX_RING_SIZE;
127 break;
128 case OID_GEN_RECEIVE_BUFFER_SPACE:
129 /* pkts times sizeof ring, maybe? */
130 // temp_data = XN_MAX_PKT_SIZE * NET_RX_RING_SIZE;
131 temp_data = PAGE_SIZE * NET_RX_RING_SIZE;
132 break;
133 case OID_GEN_TRANSMIT_BLOCK_SIZE:
134 temp_data = PAGE_SIZE; //XN_MAX_PKT_SIZE;
135 break;
136 case OID_GEN_RECEIVE_BLOCK_SIZE:
137 temp_data = PAGE_SIZE; //XN_MAX_PKT_SIZE;
138 break;
139 case OID_GEN_VENDOR_ID:
140 temp_data = 0xFFFFFF; // Not guaranteed to be XENSOURCE_MAC_HDR;
141 break;
142 case OID_GEN_VENDOR_DESCRIPTION:
143 data = vendor_desc;
144 len = sizeof(vendor_desc);
145 break;
146 case OID_GEN_CURRENT_PACKET_FILTER:
147 temp_data = xi->packet_filter;
148 break;
149 case OID_GEN_CURRENT_LOOKAHEAD:
150 // TODO: we should store this...
151 temp_data = 54; //XN_MAX_PKT_SIZE;
152 break;
153 case OID_GEN_DRIVER_VERSION:
154 temp_data = (NDIS_MINIPORT_MAJOR_VERSION << 8) | NDIS_MINIPORT_MINOR_VERSION;
155 len = 2;
156 break;
157 case OID_GEN_MAXIMUM_TOTAL_SIZE:
158 temp_data = xi->config_max_pkt_size;
159 break;
160 case OID_GEN_MAC_OPTIONS:
161 temp_data = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
162 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
163 NDIS_MAC_OPTION_NO_LOOPBACK;
164 break;
165 case OID_GEN_MEDIA_CONNECT_STATUS:
166 if (xi->connected)
167 temp_data = NdisMediaStateConnected;
168 else
169 temp_data = NdisMediaStateDisconnected;
170 break;
171 case OID_GEN_MAXIMUM_SEND_PACKETS:
172 temp_data = XN_MAX_SEND_PKTS;
173 break;
174 case OID_GEN_XMIT_OK:
175 temp_data = xi->stat_tx_ok;
176 HANDLE_STAT_RETURN;
177 break;
178 case OID_GEN_RCV_OK:
179 temp_data = xi->stat_rx_ok;
180 HANDLE_STAT_RETURN;
181 break;
182 case OID_GEN_XMIT_ERROR:
183 temp_data = xi->stat_tx_error;
184 HANDLE_STAT_RETURN;
185 break;
186 case OID_GEN_RCV_ERROR:
187 temp_data = xi->stat_rx_error;
188 HANDLE_STAT_RETURN;
189 break;
190 case OID_GEN_RCV_NO_BUFFER:
191 temp_data = xi->stat_rx_no_buffer;
192 HANDLE_STAT_RETURN;
193 break;
194 case OID_802_3_PERMANENT_ADDRESS:
195 data = xi->perm_mac_addr;
196 len = ETH_ALEN;
197 break;
198 case OID_802_3_CURRENT_ADDRESS:
199 data = xi->curr_mac_addr;
200 len = ETH_ALEN;
201 break;
202 case OID_802_3_MULTICAST_LIST:
203 data = NULL;
204 len = 0;
205 case OID_802_3_MAXIMUM_LIST_SIZE:
206 temp_data = 0; /* no mcast support */
207 break;
208 case OID_TCP_TASK_OFFLOAD:
209 KdPrint(("Get OID_TCP_TASK_OFFLOAD\n"));
210 /* it's times like this that C really sucks */
212 len = sizeof(NDIS_TASK_OFFLOAD_HEADER);
214 if (xi->config_csum)
215 {
216 len += FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
217 + sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
218 }
220 if (xi->config_gso)
221 {
222 len += FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
223 + sizeof(NDIS_TASK_TCP_LARGE_SEND);
224 }
226 if (len > InformationBufferLength)
227 {
228 break;
229 }
230 KdPrint(("InformationBuffer = %p\n", InformationBuffer));
231 KdPrint(("len = %d\n", len));
233 ntoh = (PNDIS_TASK_OFFLOAD_HEADER)InformationBuffer;
234 KdPrint(("ntoh = %p\n", ntoh));
235 if (ntoh->Version != NDIS_TASK_OFFLOAD_VERSION
236 || ntoh->Size != sizeof(*ntoh)
237 || ntoh->EncapsulationFormat.Encapsulation != IEEE_802_3_Encapsulation)
238 {
239 status = NDIS_STATUS_NOT_SUPPORTED;
240 break;
241 }
242 ntoh->OffsetFirstTask = 0;
243 nto = NULL;
245 if (xi->config_csum)
246 {
247 KdPrint(("config_csum enabled\n"));
248 if (ntoh->OffsetFirstTask == 0)
249 {
250 ntoh->OffsetFirstTask = ntoh->Size;
251 nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(ntoh) + ntoh->OffsetFirstTask);
252 }
253 else
254 {
255 nto->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
256 + nto->TaskBufferLength;
257 nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(nto) + nto->OffsetNextTask);
258 }
259 KdPrint(("nto = %p\n", nto));
260 /* fill in first nto */
261 nto->Version = NDIS_TASK_OFFLOAD_VERSION;
262 nto->Size = sizeof(NDIS_TASK_OFFLOAD);
263 nto->Task = TcpIpChecksumNdisTask;
264 nto->TaskBufferLength = sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
266 /* fill in checksum offload struct */
267 nttic = (PNDIS_TASK_TCP_IP_CHECKSUM)nto->TaskBuffer;
268 nttic->V4Transmit.IpChecksum = 0;
269 nttic->V4Transmit.IpOptionsSupported = 0;
270 nttic->V4Transmit.TcpChecksum = 1;
271 nttic->V4Transmit.TcpOptionsSupported = 1;
272 nttic->V4Transmit.UdpChecksum = 1;
273 nttic->V4Receive.IpChecksum = 1;
274 nttic->V4Receive.IpOptionsSupported = 1;
275 nttic->V4Receive.TcpChecksum = 1;
276 nttic->V4Receive.TcpOptionsSupported = 1;
277 nttic->V4Receive.UdpChecksum = 1;
278 nttic->V6Transmit.IpOptionsSupported = 0;
279 nttic->V6Transmit.TcpOptionsSupported = 0;
280 nttic->V6Transmit.TcpChecksum = 0;
281 nttic->V6Transmit.UdpChecksum = 0;
282 nttic->V6Receive.IpOptionsSupported = 0;
283 nttic->V6Receive.TcpOptionsSupported = 0;
284 nttic->V6Receive.TcpChecksum = 0;
285 nttic->V6Receive.UdpChecksum = 0;
286 }
287 if (xi->config_gso)
288 {
289 KdPrint(("config_gso enabled\n"));
290 if (ntoh->OffsetFirstTask == 0)
291 {
292 ntoh->OffsetFirstTask = ntoh->Size;
293 nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(ntoh) + ntoh->OffsetFirstTask);
294 }
295 else
296 {
297 nto->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
298 + nto->TaskBufferLength;
299 nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(nto) + nto->OffsetNextTask);
300 }
301 KdPrint(("nto = %p\n", nto));
303 /* fill in second nto */
304 nto->Version = NDIS_TASK_OFFLOAD_VERSION;
305 nto->Size = sizeof(NDIS_TASK_OFFLOAD);
306 nto->Task = TcpLargeSendNdisTask;
307 nto->TaskBufferLength = sizeof(NDIS_TASK_TCP_LARGE_SEND);
309 /* fill in large send struct */
310 nttls = (PNDIS_TASK_TCP_LARGE_SEND)nto->TaskBuffer;
311 nttls->Version = 0;
312 nttls->MaxOffLoadSize = xi->config_gso;
313 nttls->MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
314 nttls->TcpOptions = TRUE;
315 nttls->IpOptions = TRUE;
316 }
318 if (!nto)
319 nto->OffsetNextTask = 0; /* last one */
321 used_temp_buffer = FALSE;
322 break;
323 default:
324 KdPrint(("Get Unknown OID 0x%x\n", Oid));
325 status = NDIS_STATUS_NOT_SUPPORTED;
326 }
328 if (!NT_SUCCESS(status))
329 {
330 // KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (returned error)\n"));
331 return status;
332 }
334 if (len > InformationBufferLength)
335 {
336 *BytesNeeded = len;
337 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (BUFFER_TOO_SHORT)\n"));
338 return NDIS_STATUS_BUFFER_TOO_SHORT;
339 }
341 *BytesWritten = len;
342 if (len && used_temp_buffer)
343 {
344 NdisMoveMemory((PUCHAR)InformationBuffer, data, len);
345 }
347 //KdPrint(("Got OID 0x%x\n", Oid));
348 // KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
350 return status;
351 }
353 NDIS_STATUS
354 XenNet_SetInformation(
355 IN NDIS_HANDLE MiniportAdapterContext,
356 IN NDIS_OID Oid,
357 IN PVOID InformationBuffer,
358 IN ULONG InformationBufferLength,
359 OUT PULONG BytesRead,
360 OUT PULONG BytesNeeded
361 )
362 {
363 NTSTATUS status;
364 struct xennet_info *xi = MiniportAdapterContext;
365 PULONG64 data = InformationBuffer;
366 PNDIS_TASK_OFFLOAD_HEADER ntoh;
367 PNDIS_TASK_OFFLOAD nto;
368 PNDIS_TASK_TCP_IP_CHECKSUM nttic;
369 PNDIS_TASK_TCP_LARGE_SEND nttls;
370 int offset;
372 // KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
374 UNREFERENCED_PARAMETER(MiniportAdapterContext);
375 UNREFERENCED_PARAMETER(InformationBufferLength);
376 UNREFERENCED_PARAMETER(BytesRead);
377 UNREFERENCED_PARAMETER(BytesNeeded);
379 switch(Oid)
380 {
381 case OID_GEN_SUPPORTED_LIST:
382 status = NDIS_STATUS_NOT_SUPPORTED;
383 KdPrint(("Unsupported set OID_GEN_SUPPORTED_LIST\n"));
384 break;
385 case OID_GEN_HARDWARE_STATUS:
386 status = NDIS_STATUS_NOT_SUPPORTED;
387 KdPrint(("Unsupported set OID_GEN_HARDWARE_STATUS\n"));
388 break;
389 case OID_GEN_MEDIA_SUPPORTED:
390 status = NDIS_STATUS_NOT_SUPPORTED;
391 KdPrint(("Unsupported set OID_GEN_MEDIA_SUPPORTED\n"));
392 break;
393 case OID_GEN_MEDIA_IN_USE:
394 status = NDIS_STATUS_NOT_SUPPORTED;
395 KdPrint(("Unsupported set OID_GEN_MEDIA_IN_USE\n"));
396 break;
397 case OID_GEN_MAXIMUM_LOOKAHEAD:
398 status = NDIS_STATUS_NOT_SUPPORTED;
399 KdPrint(("Unsupported set OID_GEN_MAXIMUM_LOOKAHEAD\n"));
400 break;
401 case OID_GEN_MAXIMUM_FRAME_SIZE:
402 status = NDIS_STATUS_NOT_SUPPORTED;
403 KdPrint(("Unsupported set OID_GEN_MAXIMUM_FRAME_SIZE\n"));
404 break;
405 case OID_GEN_LINK_SPEED:
406 status = NDIS_STATUS_NOT_SUPPORTED;
407 KdPrint(("Unsupported set OID_GEN_LINK_SPEED\n"));
408 break;
409 case OID_GEN_TRANSMIT_BUFFER_SPACE:
410 status = NDIS_STATUS_NOT_SUPPORTED;
411 KdPrint(("Unsupported set OID_GEN_TRANSMIT_BUFFER_SPACE\n"));
412 break;
413 case OID_GEN_RECEIVE_BUFFER_SPACE:
414 status = NDIS_STATUS_NOT_SUPPORTED;
415 KdPrint(("Unsupported set OID_GEN_RECEIVE_BUFFER_SPACE\n"));
416 break;
417 case OID_GEN_TRANSMIT_BLOCK_SIZE:
418 status = NDIS_STATUS_NOT_SUPPORTED;
419 KdPrint(("Unsupported set OID_GEN_TRANSMIT_BLOCK_SIZE\n"));
420 break;
421 case OID_GEN_RECEIVE_BLOCK_SIZE:
422 status = NDIS_STATUS_NOT_SUPPORTED;
423 KdPrint(("Unsupported set OID_GEN_RECEIVE_BLOCK_SIZE\n"));
424 break;
425 case OID_GEN_VENDOR_ID:
426 status = NDIS_STATUS_NOT_SUPPORTED;
427 KdPrint(("Unsupported set OID_GEN_VENDOR_ID\n"));
428 break;
429 case OID_GEN_VENDOR_DESCRIPTION:
430 status = NDIS_STATUS_NOT_SUPPORTED;
431 KdPrint(("Unsupported set OID_GEN_VENDOR_DESCRIPTION\n"));
432 break;
433 case OID_GEN_CURRENT_PACKET_FILTER:
434 KdPrint(("Set OID_GEN_CURRENT_PACKET_FILTER\n"));
435 xi->packet_filter = *(ULONG *)data;
436 status = NDIS_STATUS_SUCCESS;
437 break;
438 case OID_GEN_CURRENT_LOOKAHEAD:
439 KdPrint(("Set OID_GEN_CURRENT_LOOKAHEAD %d\n", *(int *)data));
440 // TODO: We should do this...
441 status = NDIS_STATUS_SUCCESS;
442 break;
443 case OID_GEN_DRIVER_VERSION:
444 status = NDIS_STATUS_NOT_SUPPORTED;
445 KdPrint(("Unsupported set OID_GEN_DRIVER_VERSION\n"));
446 break;
447 case OID_GEN_MAXIMUM_TOTAL_SIZE:
448 status = NDIS_STATUS_NOT_SUPPORTED;
449 KdPrint(("Unsupported set OID_GEN_MAXIMUM_TOTAL_SIZE\n"));
450 break;
451 case OID_GEN_PROTOCOL_OPTIONS:
452 KdPrint(("Unsupported set OID_GEN_PROTOCOL_OPTIONS\n"));
453 // TODO - actually do this...
454 status = NDIS_STATUS_SUCCESS;
455 break;
456 case OID_GEN_MAC_OPTIONS:
457 status = NDIS_STATUS_NOT_SUPPORTED;
458 KdPrint(("Unsupported set OID_GEN_MAC_OPTIONS\n"));
459 break;
460 case OID_GEN_MEDIA_CONNECT_STATUS:
461 status = NDIS_STATUS_NOT_SUPPORTED;
462 KdPrint(("Unsupported set OID_GEN_MEDIA_CONNECT_STATUS\n"));
463 break;
464 case OID_GEN_MAXIMUM_SEND_PACKETS:
465 status = NDIS_STATUS_NOT_SUPPORTED;
466 KdPrint(("Unsupported set OID_GEN_MAXIMUM_SEND_PACKETS\n"));
467 break;
468 case OID_GEN_XMIT_OK:
469 status = NDIS_STATUS_NOT_SUPPORTED;
470 KdPrint(("Unsupported set OID_GEN_XMIT_OK\n"));
471 break;
472 case OID_GEN_RCV_OK:
473 status = NDIS_STATUS_NOT_SUPPORTED;
474 KdPrint(("Unsupported set OID_GEN_RCV_OK\n"));
475 break;
476 case OID_GEN_XMIT_ERROR:
477 status = NDIS_STATUS_NOT_SUPPORTED;
478 KdPrint(("Unsupported set OID_GEN_XMIT_ERROR\n"));
479 break;
480 case OID_GEN_RCV_ERROR:
481 status = NDIS_STATUS_NOT_SUPPORTED;
482 KdPrint(("Unsupported set OID_GEN_RCV_ERROR\n"));
483 break;
484 case OID_GEN_RCV_NO_BUFFER:
485 status = NDIS_STATUS_NOT_SUPPORTED;
486 KdPrint(("Unsupported set OID_GEN_RCV_NO_BUFFER\n"));
487 break;
488 case OID_802_3_PERMANENT_ADDRESS:
489 status = NDIS_STATUS_NOT_SUPPORTED;
490 KdPrint(("Unsupported set OID_802_3_PERMANENT_ADDRESS\n"));
491 break;
492 case OID_802_3_CURRENT_ADDRESS:
493 status = NDIS_STATUS_NOT_SUPPORTED;
494 KdPrint(("Unsupported set OID_802_3_CURRENT_ADDRESS\n"));
495 break;
496 case OID_802_3_MULTICAST_LIST:
497 status = NDIS_STATUS_NOT_SUPPORTED;
498 KdPrint(("Unsupported set OID_802_3_MULTICAST_LIST\n"));
499 break;
500 case OID_802_3_MAXIMUM_LIST_SIZE:
501 status = NDIS_STATUS_NOT_SUPPORTED;
502 KdPrint(("Unsupported set OID_802_3_MAXIMUM_LIST_SIZE\n"));
503 break;
504 case OID_TCP_TASK_OFFLOAD:
505 // Just fake this for now... ultimately we need to manually calc rx checksum if offload is disabled by windows
506 status = NDIS_STATUS_SUCCESS;
507 KdPrint(("Set OID_TCP_TASK_OFFLOAD\n"));
508 // we should disable everything here, then enable what has been set
509 ntoh = (PNDIS_TASK_OFFLOAD_HEADER)InformationBuffer;
510 *BytesRead = sizeof(NDIS_TASK_OFFLOAD_HEADER);
511 offset = ntoh->OffsetFirstTask;
512 nto = (PNDIS_TASK_OFFLOAD)ntoh; // not really, just to get the first offset right
513 while (offset != 0)
514 {
515 *BytesRead += FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer);
516 nto = (PNDIS_TASK_OFFLOAD)(((PUCHAR)nto) + offset);
517 switch (nto->Task)
518 {
519 case TcpIpChecksumNdisTask:
520 *BytesRead += sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
521 KdPrint(("TcpIpChecksumNdisTask\n"));
522 nttic = (PNDIS_TASK_TCP_IP_CHECKSUM)nto->TaskBuffer;
523 KdPrint((" V4Transmit.IpOptionsSupported = %d\n", nttic->V4Transmit.IpOptionsSupported));
524 KdPrint((" V4Transmit.TcpOptionsSupported = %d\n", nttic->V4Transmit.TcpOptionsSupported));
525 KdPrint((" V4Transmit.TcpChecksum = %d\n", nttic->V4Transmit.TcpChecksum));
526 KdPrint((" V4Transmit.UdpChecksum = %d\n", nttic->V4Transmit.UdpChecksum));
527 KdPrint((" V4Transmit.IpChecksum = %d\n", nttic->V4Transmit.IpChecksum));
528 KdPrint((" V4Receive.IpOptionsSupported = %d\n", nttic->V4Receive.IpOptionsSupported));
529 KdPrint((" V4Receive.TcpOptionsSupported = %d\n", nttic->V4Receive.TcpOptionsSupported));
530 KdPrint((" V4Receive.TcpChecksum = %d\n", nttic->V4Receive.TcpChecksum));
531 KdPrint((" V4Receive.UdpChecksum = %d\n", nttic->V4Receive.UdpChecksum));
532 KdPrint((" V4Receive.IpChecksum = %d\n", nttic->V4Receive.IpChecksum));
533 KdPrint((" V6Transmit.IpOptionsSupported = %d\n", nttic->V6Transmit.IpOptionsSupported));
534 KdPrint((" V6Transmit.TcpOptionsSupported = %d\n", nttic->V6Transmit.TcpOptionsSupported));
535 KdPrint((" V6Transmit.TcpChecksum = %d\n", nttic->V6Transmit.TcpChecksum));
536 KdPrint((" V6Transmit.UdpChecksum = %d\n", nttic->V6Transmit.UdpChecksum));
537 KdPrint((" V6Receive.IpOptionsSupported = %d\n", nttic->V6Receive.IpOptionsSupported));
538 KdPrint((" V6Receive.TcpOptionsSupported = %d\n", nttic->V6Receive.TcpOptionsSupported));
539 KdPrint((" V6Receive.TcpChecksum = %d\n", nttic->V6Receive.TcpChecksum));
540 KdPrint((" V6Receive.UdpChecksum = %d\n", nttic->V6Receive.UdpChecksum));
541 break;
542 case TcpLargeSendNdisTask:
543 *BytesRead += sizeof(NDIS_TASK_TCP_LARGE_SEND);
544 KdPrint(("TcpLargeSendNdisTask\n"));
545 nttls = (PNDIS_TASK_TCP_LARGE_SEND)nto->TaskBuffer;
546 KdPrint((" MaxOffLoadSize = %d\n", nttls->MaxOffLoadSize));
547 KdPrint((" MinSegmentCount = %d\n", nttls->MinSegmentCount));
548 KdPrint((" TcpOptions = %d\n", nttls->TcpOptions));
549 KdPrint((" IpOptions = %d\n", nttls->IpOptions));
550 break;
551 default:
552 KdPrint((" Unknown Task %d\n", nto->Task));
553 }
554 offset = nto->OffsetNextTask;
555 }
556 break;
557 default:
558 KdPrint(("Set Unknown OID 0x%x\n", Oid));
559 status = NDIS_STATUS_NOT_SUPPORTED;
560 break;
561 }
562 // KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
563 return status;
564 }