win-pvdrivers

view xennet/xennet_oid.c @ 589:e99c24e36f2f

Fixed newlines
author James Harper <james.harper@bendigoit.com.au>
date Tue Jun 09 12:31:57 2009 +1000 (2009-06-09)
parents b0b8be2d30c0
children d1754b0e1ead
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 };
67 /* return 4 or 8 depending on size of buffer */
68 #define HANDLE_STAT_RETURN \
69 {if (InformationBufferLength == 4) { \
70 len = 4; *BytesNeeded = 8; \
71 } else { \
72 len = 8; \
73 } }
75 NDIS_STATUS DDKAPI
76 XenNet_QueryInformation(
77 IN NDIS_HANDLE MiniportAdapterContext,
78 IN NDIS_OID Oid,
79 IN PVOID InformationBuffer,
80 IN ULONG InformationBufferLength,
81 OUT PULONG BytesWritten,
82 OUT PULONG BytesNeeded)
83 {
84 struct xennet_info *xi = MiniportAdapterContext;
85 UCHAR vendor_desc[] = XN_VENDOR_DESC;
86 ULONG64 temp_data;
87 PVOID data = &temp_data;
88 UINT len = 4;
89 BOOLEAN used_temp_buffer = TRUE;
90 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
91 PNDIS_TASK_OFFLOAD_HEADER ntoh;
92 PNDIS_TASK_OFFLOAD nto;
93 PNDIS_TASK_TCP_IP_CHECKSUM nttic;
94 PNDIS_TASK_TCP_LARGE_SEND nttls;
96 *BytesNeeded = 0;
97 *BytesWritten = 0;
99 // FUNCTION_ENTER()
101 switch(Oid)
102 {
103 case OID_GEN_SUPPORTED_LIST:
104 data = supported_oids;
105 len = sizeof(supported_oids);
106 break;
107 case OID_GEN_HARDWARE_STATUS:
108 if (!xi->connected)
109 {
110 temp_data = NdisHardwareStatusInitializing;
111 FUNCTION_MSG("NdisHardwareStatusInitializing\n");
112 }
113 else
114 {
115 temp_data = NdisHardwareStatusReady;
116 FUNCTION_MSG("NdisHardwareStatusReady\n");
117 }
118 break;
119 case OID_GEN_MEDIA_SUPPORTED:
120 temp_data = NdisMedium802_3;
121 break;
122 case OID_GEN_MEDIA_IN_USE:
123 temp_data = NdisMedium802_3;
124 break;
125 case OID_GEN_MAXIMUM_LOOKAHEAD:
126 temp_data = xi->config_mtu;
127 break;
128 case OID_GEN_MAXIMUM_FRAME_SIZE:
129 temp_data = xi->config_mtu;
130 break;
131 case OID_GEN_LINK_SPEED:
132 temp_data = 10000000; /* 1Gb */
133 break;
134 case OID_GEN_TRANSMIT_BUFFER_SPACE:
135 /* multiply this by some small number as we can queue additional packets */
136 temp_data = PAGE_SIZE * NET_TX_RING_SIZE * 4;
137 break;
138 case OID_GEN_RECEIVE_BUFFER_SPACE:
139 temp_data = PAGE_SIZE * NET_RX_RING_SIZE * 2;
140 break;
141 case OID_GEN_TRANSMIT_BLOCK_SIZE:
142 temp_data = PAGE_SIZE; //XN_MAX_PKT_SIZE;
143 break;
144 case OID_GEN_RECEIVE_BLOCK_SIZE:
145 temp_data = PAGE_SIZE; //XN_MAX_PKT_SIZE;
146 break;
147 case OID_GEN_VENDOR_ID:
148 temp_data = 0xFFFFFF; // Not guaranteed to be XENSOURCE_MAC_HDR;
149 break;
150 case OID_GEN_VENDOR_DESCRIPTION:
151 data = vendor_desc;
152 len = sizeof(vendor_desc);
153 break;
154 case OID_GEN_CURRENT_PACKET_FILTER:
155 temp_data = xi->packet_filter;
156 break;
157 case OID_GEN_CURRENT_LOOKAHEAD:
158 temp_data = xi->config_mtu;
159 break;
160 case OID_GEN_DRIVER_VERSION:
161 temp_data = (NDIS_MINIPORT_MAJOR_VERSION << 8) | NDIS_MINIPORT_MINOR_VERSION;
162 len = 2;
163 break;
164 case OID_GEN_VENDOR_DRIVER_VERSION:
165 temp_data = VENDOR_DRIVER_VERSION;
166 len = 4;
167 break;
168 case OID_GEN_MAXIMUM_TOTAL_SIZE:
169 temp_data = xi->config_mtu + XN_HDR_SIZE;
170 break;
171 case OID_GEN_MAC_OPTIONS:
172 temp_data = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
173 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
174 NDIS_MAC_OPTION_NO_LOOPBACK;
175 break;
176 case OID_GEN_MEDIA_CONNECT_STATUS:
177 if (xi->connected && !xi->inactive)
178 temp_data = NdisMediaStateConnected;
179 else
180 temp_data = NdisMediaStateDisconnected;
181 break;
182 case OID_GEN_MAXIMUM_SEND_PACKETS:
183 /* this is actually ignored for deserialised drivers like us */
184 temp_data = 0; //XN_MAX_SEND_PKTS;
185 break;
186 case OID_GEN_XMIT_OK:
187 temp_data = xi->stat_tx_ok;
188 HANDLE_STAT_RETURN;
189 break;
190 case OID_GEN_RCV_OK:
191 temp_data = xi->stat_rx_ok;
192 HANDLE_STAT_RETURN;
193 break;
194 case OID_GEN_XMIT_ERROR:
195 temp_data = xi->stat_tx_error;
196 HANDLE_STAT_RETURN;
197 break;
198 case OID_GEN_RCV_ERROR:
199 temp_data = xi->stat_rx_error;
200 HANDLE_STAT_RETURN;
201 break;
202 case OID_GEN_RCV_NO_BUFFER:
203 temp_data = xi->stat_rx_no_buffer;
204 HANDLE_STAT_RETURN;
205 break;
206 case OID_802_3_PERMANENT_ADDRESS:
207 data = xi->perm_mac_addr;
208 len = ETH_ALEN;
209 break;
210 case OID_802_3_CURRENT_ADDRESS:
211 data = xi->curr_mac_addr;
212 len = ETH_ALEN;
213 break;
214 case OID_802_3_RCV_ERROR_ALIGNMENT:
215 case OID_802_3_XMIT_ONE_COLLISION:
216 case OID_802_3_XMIT_MORE_COLLISIONS:
217 temp_data = 0;
218 HANDLE_STAT_RETURN;
219 break;
220 case OID_802_3_MULTICAST_LIST:
221 data = xi->multicast_list;
222 len = xi->multicast_list_size * 6;
223 break;
224 case OID_802_3_MAXIMUM_LIST_SIZE:
225 temp_data = MULTICAST_LIST_MAX_SIZE; /* no mcast support, but to return 0 is an error */
226 break;
227 case OID_TCP_TASK_OFFLOAD:
228 KdPrint(("Get OID_TCP_TASK_OFFLOAD\n"));
229 /* it's times like this that C really sucks */
231 len = sizeof(NDIS_TASK_OFFLOAD_HEADER);
233 if (xi->config_csum)
234 {
235 len += FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
236 + sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
237 }
239 if (xi->config_gso)
240 {
241 len += FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
242 + sizeof(NDIS_TASK_TCP_LARGE_SEND);
243 }
245 //len += 1024;
247 if (len > InformationBufferLength)
248 {
249 break;
250 }
252 ntoh = (PNDIS_TASK_OFFLOAD_HEADER)InformationBuffer;
253 if (ntoh->Version != NDIS_TASK_OFFLOAD_VERSION
254 || ntoh->Size != sizeof(*ntoh)
255 || !(
256 ntoh->EncapsulationFormat.Encapsulation == IEEE_802_3_Encapsulation
257 || (ntoh->EncapsulationFormat.Encapsulation == UNSPECIFIED_Encapsulation
258 && ntoh->EncapsulationFormat.EncapsulationHeaderSize == XN_HDR_SIZE)))
259 {
260 status = NDIS_STATUS_NOT_SUPPORTED;
261 break;
262 }
263 ntoh->OffsetFirstTask = 0;
264 nto = NULL;
266 if (xi->config_csum)
267 {
268 if (ntoh->OffsetFirstTask == 0)
269 {
270 ntoh->OffsetFirstTask = ntoh->Size;
271 nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(ntoh) + ntoh->OffsetFirstTask);
272 }
273 else
274 {
275 nto->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
276 + nto->TaskBufferLength;
277 nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(nto) + nto->OffsetNextTask);
278 }
279 /* fill in first nto */
280 nto->Version = NDIS_TASK_OFFLOAD_VERSION;
281 nto->Size = sizeof(NDIS_TASK_OFFLOAD);
282 nto->Task = TcpIpChecksumNdisTask;
283 nto->TaskBufferLength = sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
285 KdPrint(("config_csum enabled\n"));
286 KdPrint(("nto = %p\n", nto));
287 KdPrint(("nto->Size = %d\n", nto->Size));
288 KdPrint(("nto->TaskBufferLength = %d\n", nto->TaskBufferLength));
290 /* fill in checksum offload struct */
291 nttic = (PNDIS_TASK_TCP_IP_CHECKSUM)nto->TaskBuffer;
292 nttic->V4Transmit.IpChecksum = 0;
293 nttic->V4Transmit.IpOptionsSupported = 0;
294 nttic->V4Transmit.TcpChecksum = 1;
295 nttic->V4Transmit.TcpOptionsSupported = 1;
296 nttic->V4Transmit.UdpChecksum = 1;
297 nttic->V4Receive.IpChecksum = 0;
298 nttic->V4Receive.IpOptionsSupported = 0;
299 nttic->V4Receive.TcpChecksum = 1;
300 nttic->V4Receive.TcpOptionsSupported = 1;
301 nttic->V4Receive.UdpChecksum = 1;
302 nttic->V6Transmit.IpOptionsSupported = 0;
303 nttic->V6Transmit.TcpOptionsSupported = 0;
304 nttic->V6Transmit.TcpChecksum = 0;
305 nttic->V6Transmit.UdpChecksum = 0;
306 nttic->V6Receive.IpOptionsSupported = 0;
307 nttic->V6Receive.TcpOptionsSupported = 0;
308 nttic->V6Receive.TcpChecksum = 0;
309 nttic->V6Receive.UdpChecksum = 0;
310 }
311 if (xi->config_gso)
312 {
313 if (ntoh->OffsetFirstTask == 0)
314 {
315 ntoh->OffsetFirstTask = ntoh->Size;
316 nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(ntoh) + ntoh->OffsetFirstTask);
317 }
318 else
319 {
320 nto->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
321 + nto->TaskBufferLength;
322 nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(nto) + nto->OffsetNextTask);
323 }
325 /* fill in second nto */
326 nto->Version = NDIS_TASK_OFFLOAD_VERSION;
327 nto->Size = sizeof(NDIS_TASK_OFFLOAD);
328 nto->Task = TcpLargeSendNdisTask;
329 nto->TaskBufferLength = sizeof(NDIS_TASK_TCP_LARGE_SEND);
331 KdPrint(("config_gso enabled\n"));
332 KdPrint(("nto = %p\n", nto));
333 KdPrint(("nto->Size = %d\n", nto->Size));
334 KdPrint(("nto->TaskBufferLength = %d\n", nto->TaskBufferLength));
336 /* fill in large send struct */
337 nttls = (PNDIS_TASK_TCP_LARGE_SEND)nto->TaskBuffer;
338 nttls->Version = 0;
339 nttls->MaxOffLoadSize = xi->config_gso;
340 nttls->MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
341 nttls->TcpOptions = FALSE; /* linux can't handle this */
342 nttls->IpOptions = FALSE; /* linux can't handle this */
343 KdPrint(("&(nttls->IpOptions) = %p\n", &(nttls->IpOptions)));
344 }
346 if (nto)
347 nto->OffsetNextTask = 0; /* last one */
349 used_temp_buffer = FALSE;
350 break;
351 case OID_IP4_OFFLOAD_STATS:
352 case OID_IP6_OFFLOAD_STATS:
353 /* these are called often so just ignore then quietly */
354 status = NDIS_STATUS_NOT_SUPPORTED;
355 break;
356 default:
357 KdPrint(("Get Unknown OID 0x%x\n", Oid));
358 status = NDIS_STATUS_NOT_SUPPORTED;
359 }
361 if (!NT_SUCCESS(status))
362 {
363 // FUNCTION_ERROR_EXIT();
364 return status;
365 }
367 if (len > InformationBufferLength)
368 {
369 *BytesNeeded = len;
370 FUNCTION_MSG("(BUFFER_TOO_SHORT %d > %d)\n", len, InformationBufferLength);
371 return NDIS_STATUS_BUFFER_TOO_SHORT;
372 }
374 *BytesWritten = len;
375 if (len && used_temp_buffer)
376 {
377 NdisMoveMemory((PUCHAR)InformationBuffer, data, len);
378 }
380 //KdPrint(("Got OID 0x%x\n", Oid));
381 // KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
383 return status;
384 }
386 NDIS_STATUS DDKAPI
387 XenNet_SetInformation(
388 IN NDIS_HANDLE MiniportAdapterContext,
389 IN NDIS_OID Oid,
390 IN PVOID InformationBuffer,
391 IN ULONG InformationBufferLength,
392 OUT PULONG BytesRead,
393 OUT PULONG BytesNeeded
394 )
395 {
396 NTSTATUS status;
397 ULONG i;
398 struct xennet_info *xi = MiniportAdapterContext;
399 PULONG64 data = InformationBuffer;
400 PNDIS_TASK_OFFLOAD_HEADER ntoh;
401 PNDIS_TASK_OFFLOAD nto;
402 PNDIS_TASK_TCP_IP_CHECKSUM nttic = NULL;
403 PNDIS_TASK_TCP_LARGE_SEND nttls = NULL;
404 UCHAR *multicast_list;
405 int offset;
407 //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
409 UNREFERENCED_PARAMETER(MiniportAdapterContext);
410 UNREFERENCED_PARAMETER(InformationBufferLength);
411 UNREFERENCED_PARAMETER(BytesRead);
412 UNREFERENCED_PARAMETER(BytesNeeded);
414 switch(Oid)
415 {
416 case OID_GEN_SUPPORTED_LIST:
417 status = NDIS_STATUS_NOT_SUPPORTED;
418 KdPrint(("Unsupported set OID_GEN_SUPPORTED_LIST\n"));
419 break;
420 case OID_GEN_HARDWARE_STATUS:
421 status = NDIS_STATUS_NOT_SUPPORTED;
422 KdPrint(("Unsupported set OID_GEN_HARDWARE_STATUS\n"));
423 break;
424 case OID_GEN_MEDIA_SUPPORTED:
425 status = NDIS_STATUS_NOT_SUPPORTED;
426 KdPrint(("Unsupported set OID_GEN_MEDIA_SUPPORTED\n"));
427 break;
428 case OID_GEN_MEDIA_IN_USE:
429 status = NDIS_STATUS_NOT_SUPPORTED;
430 KdPrint(("Unsupported set OID_GEN_MEDIA_IN_USE\n"));
431 break;
432 case OID_GEN_MAXIMUM_LOOKAHEAD:
433 status = NDIS_STATUS_NOT_SUPPORTED;
434 KdPrint(("Unsupported set OID_GEN_MAXIMUM_LOOKAHEAD\n"));
435 break;
436 case OID_GEN_MAXIMUM_FRAME_SIZE:
437 status = NDIS_STATUS_NOT_SUPPORTED;
438 KdPrint(("Unsupported set OID_GEN_MAXIMUM_FRAME_SIZE\n"));
439 break;
440 case OID_GEN_LINK_SPEED:
441 status = NDIS_STATUS_NOT_SUPPORTED;
442 KdPrint(("Unsupported set OID_GEN_LINK_SPEED\n"));
443 break;
444 case OID_GEN_TRANSMIT_BUFFER_SPACE:
445 status = NDIS_STATUS_NOT_SUPPORTED;
446 KdPrint(("Unsupported set OID_GEN_TRANSMIT_BUFFER_SPACE\n"));
447 break;
448 case OID_GEN_RECEIVE_BUFFER_SPACE:
449 status = NDIS_STATUS_NOT_SUPPORTED;
450 KdPrint(("Unsupported set OID_GEN_RECEIVE_BUFFER_SPACE\n"));
451 break;
452 case OID_GEN_TRANSMIT_BLOCK_SIZE:
453 status = NDIS_STATUS_NOT_SUPPORTED;
454 KdPrint(("Unsupported set OID_GEN_TRANSMIT_BLOCK_SIZE\n"));
455 break;
456 case OID_GEN_RECEIVE_BLOCK_SIZE:
457 status = NDIS_STATUS_NOT_SUPPORTED;
458 KdPrint(("Unsupported set OID_GEN_RECEIVE_BLOCK_SIZE\n"));
459 break;
460 case OID_GEN_VENDOR_ID:
461 status = NDIS_STATUS_NOT_SUPPORTED;
462 KdPrint(("Unsupported set OID_GEN_VENDOR_ID\n"));
463 break;
464 case OID_GEN_VENDOR_DESCRIPTION:
465 status = NDIS_STATUS_NOT_SUPPORTED;
466 KdPrint(("Unsupported set OID_GEN_VENDOR_DESCRIPTION\n"));
467 break;
468 case OID_GEN_CURRENT_PACKET_FILTER:
469 KdPrint(("Set OID_GEN_CURRENT_PACKET_FILTER\n"));
470 if (*(ULONG *)data & NDIS_PACKET_TYPE_DIRECTED)
471 KdPrint((" NDIS_PACKET_TYPE_DIRECTED\n"));
472 if (*(ULONG *)data & NDIS_PACKET_TYPE_MULTICAST)
473 KdPrint((" NDIS_PACKET_TYPE_MULTICAST\n"));
474 if (*(ULONG *)data & NDIS_PACKET_TYPE_ALL_MULTICAST)
475 KdPrint((" NDIS_PACKET_TYPE_ALL_MULTICAST\n"));
476 if (*(ULONG *)data & NDIS_PACKET_TYPE_BROADCAST)
477 KdPrint((" NDIS_PACKET_TYPE_BROADCAST\n"));
478 if (*(ULONG *)data & NDIS_PACKET_TYPE_PROMISCUOUS)
479 KdPrint((" NDIS_PACKET_TYPE_PROMISCUOUS\n"));
480 if (*(ULONG *)data & NDIS_PACKET_TYPE_ALL_FUNCTIONAL)
481 KdPrint((" NDIS_PACKET_TYPE_ALL_FUNCTIONAL (not supported)\n"));
482 if (*(ULONG *)data & NDIS_PACKET_TYPE_ALL_LOCAL)
483 KdPrint((" NDIS_PACKET_TYPE_ALL_LOCAL (not supported)\n"));
484 if (*(ULONG *)data & NDIS_PACKET_TYPE_FUNCTIONAL)
485 KdPrint((" NDIS_PACKET_TYPE_FUNCTIONAL (not supported)\n"));
486 if (*(ULONG *)data & NDIS_PACKET_TYPE_GROUP)
487 KdPrint((" NDIS_PACKET_TYPE_GROUP (not supported)\n"));
488 if (*(ULONG *)data & ~SUPPORTED_PACKET_FILTERS)
489 {
490 status = NDIS_STATUS_NOT_SUPPORTED;
491 KdPrint((" returning NDIS_STATUS_NOT_SUPPORTED\n"));
492 break;
493 }
494 xi->packet_filter = *(ULONG *)data;
495 status = NDIS_STATUS_SUCCESS;
496 break;
497 case OID_GEN_CURRENT_LOOKAHEAD:
498 KdPrint(("Set OID_GEN_CURRENT_LOOKAHEAD %d\n", *(int *)data));
499 // TODO: We should do this...
500 status = NDIS_STATUS_SUCCESS;
501 break;
502 case OID_GEN_DRIVER_VERSION:
503 status = NDIS_STATUS_NOT_SUPPORTED;
504 KdPrint(("Unsupported set OID_GEN_DRIVER_VERSION\n"));
505 break;
506 case OID_GEN_MAXIMUM_TOTAL_SIZE:
507 status = NDIS_STATUS_NOT_SUPPORTED;
508 KdPrint(("Unsupported set OID_GEN_MAXIMUM_TOTAL_SIZE\n"));
509 break;
510 case OID_GEN_PROTOCOL_OPTIONS:
511 KdPrint(("Unsupported set OID_GEN_PROTOCOL_OPTIONS\n"));
512 // TODO - actually do this...
513 status = NDIS_STATUS_SUCCESS;
514 break;
515 case OID_GEN_MAC_OPTIONS:
516 status = NDIS_STATUS_NOT_SUPPORTED;
517 KdPrint(("Unsupported set OID_GEN_MAC_OPTIONS\n"));
518 break;
519 case OID_GEN_MEDIA_CONNECT_STATUS:
520 status = NDIS_STATUS_NOT_SUPPORTED;
521 KdPrint(("Unsupported set OID_GEN_MEDIA_CONNECT_STATUS\n"));
522 break;
523 case OID_GEN_MAXIMUM_SEND_PACKETS:
524 status = NDIS_STATUS_NOT_SUPPORTED;
525 KdPrint(("Unsupported set OID_GEN_MAXIMUM_SEND_PACKETS\n"));
526 break;
527 case OID_GEN_XMIT_OK:
528 status = NDIS_STATUS_NOT_SUPPORTED;
529 KdPrint(("Unsupported set OID_GEN_XMIT_OK\n"));
530 break;
531 case OID_GEN_RCV_OK:
532 status = NDIS_STATUS_NOT_SUPPORTED;
533 KdPrint(("Unsupported set OID_GEN_RCV_OK\n"));
534 break;
535 case OID_GEN_XMIT_ERROR:
536 status = NDIS_STATUS_NOT_SUPPORTED;
537 KdPrint(("Unsupported set OID_GEN_XMIT_ERROR\n"));
538 break;
539 case OID_GEN_RCV_ERROR:
540 status = NDIS_STATUS_NOT_SUPPORTED;
541 KdPrint(("Unsupported set OID_GEN_RCV_ERROR\n"));
542 break;
543 case OID_GEN_RCV_NO_BUFFER:
544 status = NDIS_STATUS_NOT_SUPPORTED;
545 KdPrint(("Unsupported set OID_GEN_RCV_NO_BUFFER\n"));
546 break;
547 case OID_802_3_PERMANENT_ADDRESS:
548 status = NDIS_STATUS_NOT_SUPPORTED;
549 KdPrint(("Unsupported set OID_802_3_PERMANENT_ADDRESS\n"));
550 break;
551 case OID_802_3_CURRENT_ADDRESS:
552 status = NDIS_STATUS_NOT_SUPPORTED;
553 KdPrint(("Unsupported set OID_802_3_CURRENT_ADDRESS\n"));
554 break;
555 case OID_802_3_MULTICAST_LIST:
556 KdPrint((" Set OID_802_3_MULTICAST_LIST\n"));
557 KdPrint((" Length = %d\n", InformationBufferLength));
558 KdPrint((" Entries = %d\n", InformationBufferLength / 6));
559 if (InformationBufferLength > MULTICAST_LIST_MAX_SIZE * 6)
560 {
561 status = NDIS_STATUS_MULTICAST_FULL;
562 break;
563 }
565 if (InformationBufferLength % 6 != 0)
566 {
567 status = NDIS_STATUS_MULTICAST_FULL;
568 break;
569 }
570 multicast_list = InformationBuffer;
571 for (i = 0; i < InformationBufferLength / 6; i++)
572 {
573 if (!(multicast_list[i * 6 + 0] & 0x01))
574 {
575 KdPrint((" Address %d (%02x:%02x:%02x:%02x:%02x:%02x) is not a multicast address\n", i,
576 (ULONG)multicast_list[i * 6 + 0], (ULONG)multicast_list[i * 6 + 1],
577 (ULONG)multicast_list[i * 6 + 2], (ULONG)multicast_list[i * 6 + 3],
578 (ULONG)multicast_list[i * 6 + 4], (ULONG)multicast_list[i * 6 + 5]));
579 status = NDIS_STATUS_MULTICAST_FULL;
580 break;
581 }
582 }
583 memcpy(xi->multicast_list, InformationBuffer, InformationBufferLength);
584 xi->multicast_list_size = InformationBufferLength / 6;
585 status = NDIS_STATUS_SUCCESS;
586 break;
587 case OID_802_3_MAXIMUM_LIST_SIZE:
588 status = NDIS_STATUS_NOT_SUPPORTED;
589 KdPrint(("Unsupported set OID_802_3_MAXIMUM_LIST_SIZE\n"));
590 break;
591 case OID_TCP_TASK_OFFLOAD:
592 status = NDIS_STATUS_SUCCESS;
593 KdPrint(("Set OID_TCP_TASK_OFFLOAD\n"));
594 // we should disable everything here, then enable what has been set
595 ntoh = (PNDIS_TASK_OFFLOAD_HEADER)InformationBuffer;
596 if (ntoh->Version != NDIS_TASK_OFFLOAD_VERSION)
597 {
598 KdPrint(("Invalid version (%d passed but must be %d)\n", ntoh->Version, NDIS_TASK_OFFLOAD_VERSION));
599 status = NDIS_STATUS_INVALID_DATA;
600 break;
601 }
602 if (ntoh->Version != NDIS_TASK_OFFLOAD_VERSION || ntoh->Size != sizeof(NDIS_TASK_OFFLOAD_HEADER))
603 {
604 KdPrint(("Invalid size (%d passed but must be %d)\n", ntoh->Size, sizeof(NDIS_TASK_OFFLOAD_HEADER)));
605 status = NDIS_STATUS_INVALID_DATA;
606 break;
607 }
608 *BytesRead = sizeof(NDIS_TASK_OFFLOAD_HEADER);
609 offset = ntoh->OffsetFirstTask;
610 nto = (PNDIS_TASK_OFFLOAD)ntoh; // not really, just to get the first offset right
611 while (offset != 0)
612 {
613 *BytesRead += FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer);
614 nto = (PNDIS_TASK_OFFLOAD)(((PUCHAR)nto) + offset);
615 switch (nto->Task)
616 {
617 case TcpIpChecksumNdisTask:
618 *BytesRead += sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
619 nttic = (PNDIS_TASK_TCP_IP_CHECKSUM)nto->TaskBuffer;
620 KdPrint(("TcpIpChecksumNdisTask\n"));
621 KdPrint((" V4Transmit.IpOptionsSupported = %d\n", nttic->V4Transmit.IpOptionsSupported));
622 KdPrint((" V4Transmit.TcpOptionsSupported = %d\n", nttic->V4Transmit.TcpOptionsSupported));
623 KdPrint((" V4Transmit.TcpChecksum = %d\n", nttic->V4Transmit.TcpChecksum));
624 KdPrint((" V4Transmit.UdpChecksum = %d\n", nttic->V4Transmit.UdpChecksum));
625 KdPrint((" V4Transmit.IpChecksum = %d\n", nttic->V4Transmit.IpChecksum));
626 KdPrint((" V4Receive.IpOptionsSupported = %d\n", nttic->V4Receive.IpOptionsSupported));
627 KdPrint((" V4Receive.TcpOptionsSupported = %d\n", nttic->V4Receive.TcpOptionsSupported));
628 KdPrint((" V4Receive.TcpChecksum = %d\n", nttic->V4Receive.TcpChecksum));
629 KdPrint((" V4Receive.UdpChecksum = %d\n", nttic->V4Receive.UdpChecksum));
630 KdPrint((" V4Receive.IpChecksum = %d\n", nttic->V4Receive.IpChecksum));
631 KdPrint((" V6Transmit.IpOptionsSupported = %d\n", nttic->V6Transmit.IpOptionsSupported));
632 KdPrint((" V6Transmit.TcpOptionsSupported = %d\n", nttic->V6Transmit.TcpOptionsSupported));
633 KdPrint((" V6Transmit.TcpChecksum = %d\n", nttic->V6Transmit.TcpChecksum));
634 KdPrint((" V6Transmit.UdpChecksum = %d\n", nttic->V6Transmit.UdpChecksum));
635 KdPrint((" V6Receive.IpOptionsSupported = %d\n", nttic->V6Receive.IpOptionsSupported));
636 KdPrint((" V6Receive.TcpOptionsSupported = %d\n", nttic->V6Receive.TcpOptionsSupported));
637 KdPrint((" V6Receive.TcpChecksum = %d\n", nttic->V6Receive.TcpChecksum));
638 KdPrint((" V6Receive.UdpChecksum = %d\n", nttic->V6Receive.UdpChecksum));
639 /* check for stuff we outright don't support */
640 if (nttic->V6Transmit.IpOptionsSupported ||
641 nttic->V6Transmit.TcpOptionsSupported ||
642 nttic->V6Transmit.TcpChecksum ||
643 nttic->V6Transmit.UdpChecksum ||
644 nttic->V6Receive.IpOptionsSupported ||
645 nttic->V6Receive.TcpOptionsSupported ||
646 nttic->V6Receive.TcpChecksum ||
647 nttic->V6Receive.UdpChecksum)
648 {
649 KdPrint(("IPv6 offload not supported\n"));
650 status = NDIS_STATUS_INVALID_DATA;
651 nttic = NULL;
652 break;
653 }
654 if (nttic->V4Transmit.IpOptionsSupported ||
655 nttic->V4Transmit.IpChecksum)
656 {
657 KdPrint(("IPv4 IP Transmit offload not supported\n"));
658 status = NDIS_STATUS_INVALID_DATA;
659 nttic = NULL;
660 break;
661 }
662 if (nttic->V4Receive.IpOptionsSupported &&
663 !nttic->V4Receive.IpChecksum)
664 {
665 KdPrint(("Invalid combination\n"));
666 status = NDIS_STATUS_INVALID_DATA;
667 nttic = NULL;
668 break;
669 }
670 if (nttic->V4Transmit.TcpOptionsSupported &&
671 !nttic->V4Transmit.TcpChecksum)
672 {
673 KdPrint(("Invalid combination\n"));
674 status = NDIS_STATUS_INVALID_DATA;
675 nttic = NULL;
676 break;
677 }
678 if (nttic->V4Receive.TcpOptionsSupported &&
679 !nttic->V4Receive.TcpChecksum)
680 {
681 KdPrint(("Invalid combination\n"));
682 status = NDIS_STATUS_INVALID_DATA;
683 nttic = NULL;
684 break;
685 }
686 break;
687 case TcpLargeSendNdisTask:
688 *BytesRead += sizeof(NDIS_TASK_TCP_LARGE_SEND);
689 KdPrint(("TcpLargeSendNdisTask\n"));
690 nttls = (PNDIS_TASK_TCP_LARGE_SEND)nto->TaskBuffer;
691 KdPrint((" MaxOffLoadSize = %d\n", nttls->MaxOffLoadSize));
692 KdPrint((" MinSegmentCount = %d\n", nttls->MinSegmentCount));
693 KdPrint((" TcpOptions = %d\n", nttls->TcpOptions));
694 KdPrint((" IpOptions = %d\n", nttls->IpOptions));
695 if (nttls->MinSegmentCount != MIN_LARGE_SEND_SEGMENTS)
696 {
697 KdPrint((" MinSegmentCount should be %d\n", MIN_LARGE_SEND_SEGMENTS));
698 status = NDIS_STATUS_INVALID_DATA;
699 nttls = NULL;
700 break;
701 }
702 if (nttls->IpOptions)
703 {
704 KdPrint((" IpOptions not supported\n"));
705 status = NDIS_STATUS_INVALID_DATA;
706 nttls = NULL;
707 break;
708 }
709 if (nttls->TcpOptions)
710 {
711 KdPrint((" TcpOptions not supported\n"));
712 status = NDIS_STATUS_INVALID_DATA;
713 nttls = NULL;
714 break;
715 }
716 break;
717 default:
718 KdPrint((" Unknown Task %d\n", nto->Task));
719 }
720 offset = nto->OffsetNextTask;
721 }
722 if (nttic != NULL)
723 xi->setting_csum = *nttic;
724 else
725 {
726 RtlZeroMemory(&xi->setting_csum, sizeof(NDIS_TASK_TCP_IP_CHECKSUM));
727 KdPrint((" csum offload disabled\n", nto->Task));
728 }
729 if (nttls != NULL)
730 xi->setting_max_offload = nttls->MaxOffLoadSize;
731 else
732 {
733 xi->setting_max_offload = 0;
734 KdPrint((" LSO disabled\n", nto->Task));
735 }
736 break;
737 default:
738 KdPrint(("Set Unknown OID 0x%x\n", Oid));
739 status = NDIS_STATUS_NOT_SUPPORTED;
740 break;
741 }
742 //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
743 return status;
744 }