win-pvdrivers

annotate xennet/xennet_oid.c @ 639:16108e228997

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