win-pvdrivers

annotate xennet/xennet.c @ 1013:43e76afb2398

Fix compiler warnings under 2000
author James Harper <james.harper@bendigoit.com.au>
date Mon Feb 11 20:59:11 2013 +1100 (2013-02-11)
parents c21a4feb4a27
children 5bb1f345e06a
rev   line source
james@1007 1 /*
james@1007 2 PV Net Driver for Windows Xen HVM Domains
james@1007 3 Copyright (C) 2007 James Harper
james@1007 4 Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
james@1007 5
james@1007 6 This program is free software; you can redistribute it and/or
james@1007 7 modify it under the terms of the GNU General Public License
james@1007 8 as published by the Free Software Foundation; either version 2
james@1007 9 of the License, or (at your option) any later version.
james@1007 10
james@1007 11 This program is distributed in the hope that it will be useful,
james@1007 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
james@1007 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
james@1007 14 GNU General Public License for more details.
james@1007 15
james@1007 16 You should have received a copy of the GNU General Public License
james@1007 17 along with this program; if not, write to the Free Software
james@1007 18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
james@1007 19 */
james@1007 20
james@1007 21 #include <stdlib.h>
james@1007 22 #include <io/xenbus.h>
james@1007 23 #include "xennet.h"
james@1007 24
james@1007 25 /* Not really necessary but keeps PREfast happy */
james@1007 26 DRIVER_INITIALIZE DriverEntry;
james@1007 27 #if (VER_PRODUCTBUILD >= 7600)
james@1007 28 static KDEFERRED_ROUTINE XenNet_RxTxDpc;
james@1007 29 #endif
james@1007 30 VOID XenNet_DeviceCallback(PVOID context, ULONG callback_type, PVOID value);
james@1007 31
james@1007 32 #pragma NDIS_INIT_FUNCTION(DriverEntry)
james@1007 33
james@1007 34 NDIS_HANDLE driver_handle = NULL;
james@1007 35
james@1007 36 USHORT ndis_os_major_version = 0;
james@1007 37 USHORT ndis_os_minor_version = 0;
james@1007 38
james@1007 39 static VOID
james@1007 40 XenNet_RxTxDpc(PKDPC dpc, PVOID context, PVOID arg1, PVOID arg2)
james@1007 41 {
james@1007 42 struct xennet_info *xi = context;
james@1007 43 BOOLEAN dont_set_event;
james@1007 44
james@1007 45 UNREFERENCED_PARAMETER(dpc);
james@1007 46 UNREFERENCED_PARAMETER(arg1);
james@1007 47 UNREFERENCED_PARAMETER(arg2);
james@1007 48
james@1007 49 //FUNCTION_ENTER();
james@1007 50 /* if Rx goes over its per-dpc quota then make sure TxBufferGC doesn't set an event as we are already guaranteed to be called again */
james@1007 51 dont_set_event = XenNet_RxBufferCheck(xi);
james@1007 52 XenNet_TxBufferGC(xi, dont_set_event);
james@1007 53 //FUNCTION_EXIT();
james@1007 54 }
james@1007 55
james@1007 56 // Called at PASSIVE_LEVEL
james@1007 57 #if NTDDI_VERSION < NTDDI_VISTA
james@1007 58 static NDIS_STATUS
james@1007 59 XenNet_Init(PNDIS_STATUS open_error_status, PUINT SelectedMediumIndex, PNDIS_MEDIUM MediumArray, UINT MediumArraySize, NDIS_HANDLE adapter_handle, NDIS_HANDLE WrapperConfigurationContext)
james@914 60 #else
james@1007 61 static NDIS_STATUS
james@1007 62 XenNet_Initialize(NDIS_HANDLE adapter_handle, NDIS_HANDLE driver_context, PNDIS_MINIPORT_INIT_PARAMETERS init_parameters)
james@821 63 #endif
james@1007 64 {
james@1007 65 NDIS_STATUS status;
james@1007 66 struct xennet_info *xi = NULL;
james@1007 67 NDIS_HANDLE config_handle;
james@1007 68 PNDIS_CONFIGURATION_PARAMETER config_param;
james@1007 69 NDIS_STRING config_param_name;
james@1007 70 ULONG i;
james@1007 71 //ULONG length;
james@1007 72 PVOID network_address;
james@1007 73 UINT network_address_length;
james@1007 74 #if NTDDI_VERSION < NTDDI_VISTA
james@1007 75 #else
james@1007 76 NDIS_CONFIGURATION_OBJECT config_object;
james@1007 77 NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES registration_attributes;
james@1007 78 NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES general_attributes;
james@1007 79 NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES offload_attributes;
james@1007 80 NDIS_OFFLOAD df_offload, hw_offload;
james@1007 81 NDIS_TCP_CONNECTION_OFFLOAD df_conn_offload, hw_conn_offload;
james@1007 82 NDIS_OID *supported_oids;
james@1007 83 #endif
james@1007 84
james@1007 85 #if NTDDI_VERSION < NTDDI_VISTA
james@1007 86 UNREFERENCED_PARAMETER(open_error_status);
james@1007 87 #else
james@1007 88 UNREFERENCED_PARAMETER(driver_context);
james@1007 89 UNREFERENCED_PARAMETER(init_parameters);
james@1007 90 #endif
james@1007 91
james@1007 92 FUNCTION_ENTER();
james@1007 93
james@1007 94 #if NTDDI_VERSION < NTDDI_VISTA
james@1007 95 for (i = 0; i < MediumArraySize; i++) {
james@1007 96 if (MediumArray[i] == NdisMedium802_3) {
james@1007 97 break;
james@1007 98 }
james@1007 99 }
james@1007 100 if (i == MediumArraySize) {
james@1007 101 FUNCTION_MSG("NIC_MEDIA_TYPE not in MediumArray\n");
james@1007 102 return NDIS_STATUS_UNSUPPORTED_MEDIA;
james@1007 103 }
james@1007 104 *SelectedMediumIndex = i;
james@1007 105 #endif
james@1007 106 /* Alloc memory for adapter private info */
james@1007 107 status = NdisAllocateMemoryWithTag((PVOID)&xi, sizeof(*xi), XENNET_POOL_TAG);
james@1007 108 if (!NT_SUCCESS(status)) {
james@1007 109 FUNCTION_MSG("NdisAllocateMemoryWithTag failed with 0x%x\n", status);
james@1007 110 status = NDIS_STATUS_RESOURCES;
james@1007 111 goto err;
james@1007 112 }
james@1007 113 RtlZeroMemory(xi, sizeof(*xi));
james@1007 114 xi->adapter_handle = adapter_handle;
james@1007 115 xi->device_state = DEVICE_STATE_INITIALISING;
james@1007 116 NdisMGetDeviceProperty(xi->adapter_handle, &xi->pdo, &xi->fdo,
james@1007 117 &xi->lower_do, NULL, NULL);
james@1007 118 KeInitializeEvent(&xi->backend_event, SynchronizationEvent, FALSE);
james@1007 119
james@1007 120 #if NTDDI_VERSION < NTDDI_VISTA
james@1007 121 #endif
james@1007 122 xi->rx_target = RX_DFL_MIN_TARGET;
james@1007 123 xi->rx_min_target = RX_DFL_MIN_TARGET;
james@1007 124 xi->rx_max_target = RX_MAX_TARGET;
james@1007 125
james@1007 126 xi->multicast_list_size = 0;
james@1007 127 xi->current_lookahead = MIN_LOOKAHEAD_LENGTH;
james@1007 128
james@1007 129 #if NTDDI_VERSION < NTDDI_VISTA
james@1007 130 #else
james@1007 131 xi->stats.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
james@1007 132 xi->stats.Header.Revision = NDIS_STATISTICS_INFO_REVISION_1;
james@1007 133 xi->stats.Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1;
james@1007 134 xi->stats.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED
james@1007 135 | NDIS_STATISTICS_RCV_OK_SUPPORTED
james@1007 136 | NDIS_STATISTICS_XMIT_ERROR_SUPPORTED
james@1007 137 | NDIS_STATISTICS_RCV_ERROR_SUPPORTED
james@1007 138 | NDIS_STATISTICS_RCV_NO_BUFFER_SUPPORTED
james@1007 139 | NDIS_STATISTICS_DIRECTED_BYTES_XMIT_SUPPORTED
james@1007 140 | NDIS_STATISTICS_DIRECTED_FRAMES_XMIT_SUPPORTED
james@1007 141 | NDIS_STATISTICS_MULTICAST_BYTES_XMIT_SUPPORTED
james@1007 142 | NDIS_STATISTICS_MULTICAST_FRAMES_XMIT_SUPPORTED
james@1007 143 | NDIS_STATISTICS_BROADCAST_BYTES_XMIT_SUPPORTED
james@1007 144 | NDIS_STATISTICS_BROADCAST_FRAMES_XMIT_SUPPORTED
james@1007 145 | NDIS_STATISTICS_DIRECTED_BYTES_RCV_SUPPORTED
james@1007 146 | NDIS_STATISTICS_DIRECTED_FRAMES_RCV_SUPPORTED
james@1007 147 | NDIS_STATISTICS_MULTICAST_BYTES_RCV_SUPPORTED
james@1007 148 | NDIS_STATISTICS_MULTICAST_FRAMES_RCV_SUPPORTED
james@1007 149 | NDIS_STATISTICS_BROADCAST_BYTES_RCV_SUPPORTED
james@1007 150 | NDIS_STATISTICS_BROADCAST_FRAMES_RCV_SUPPORTED
james@1007 151 | NDIS_STATISTICS_RCV_CRC_ERROR_SUPPORTED
james@1007 152 | NDIS_STATISTICS_TRANSMIT_QUEUE_LENGTH_SUPPORTED
james@1007 153 | NDIS_STATISTICS_BYTES_RCV_SUPPORTED
james@1007 154 | NDIS_STATISTICS_BYTES_XMIT_SUPPORTED
james@1007 155 | NDIS_STATISTICS_RCV_DISCARDS_SUPPORTED
james@1007 156 | NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED
james@1007 157 | NDIS_STATISTICS_XMIT_DISCARDS_SUPPORTED;
james@1007 158 #endif
james@1007 159
james@1007 160 KeInitializeDpc(&xi->rxtx_dpc, XenNet_RxTxDpc, xi);
james@1007 161
james@1007 162 xi->packet_filter = 0;
james@1007 163
james@1007 164 #if NTDDI_VERSION < NTDDI_VISTA
james@1007 165 NdisOpenConfiguration(&status, &config_handle, WrapperConfigurationContext);
james@1007 166 #else
james@1007 167 config_object.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT);
james@1007 168 config_object.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
james@1007 169 config_object.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
james@1007 170 config_object.NdisHandle = xi->adapter_handle;
james@1007 171 config_object.Flags = 0;
james@1007 172
james@1007 173 status = NdisOpenConfigurationEx(&config_object, &config_handle);
james@1007 174 #endif
james@1007 175 if (!NT_SUCCESS(status)) {
james@1007 176 FUNCTION_MSG("Could not open config in registry (%08x)\n", status);
james@1007 177 status = NDIS_STATUS_RESOURCES;
james@1007 178 goto err;
james@1007 179 }
james@1007 180
james@1007 181 NdisInitUnicodeString(&config_param_name, L"ScatterGather");
james@1007 182 NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
james@1007 183 if (!NT_SUCCESS(status))
james@1007 184 {
james@1007 185 FUNCTION_MSG("Could not read ScatterGather value (%08x)\n", status);
james@1007 186 xi->frontend_sg_supported = TRUE;
james@1007 187 } else {
james@1007 188 FUNCTION_MSG("ScatterGather = %d\n", config_param->ParameterData.IntegerData);
james@1013 189 xi->frontend_sg_supported = (BOOLEAN)!!config_param->ParameterData.IntegerData;
james@1007 190 }
james@1007 191 if (xi->frontend_sg_supported && ndis_os_minor_version < 1) {
james@1007 192 FUNCTION_MSG("No support for SG with NDIS 6.0, disabled\n");
james@1007 193 xi->frontend_sg_supported = FALSE;
james@1007 194 }
james@1007 195
james@1007 196 NdisInitUnicodeString(&config_param_name, L"LargeSendOffload");
james@1007 197 NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
james@1007 198 if (!NT_SUCCESS(status)) {
james@1007 199 FUNCTION_MSG("Could not read LargeSendOffload value (%08x)\n", status);
james@1007 200 xi->frontend_gso_value = 0;
james@1007 201 } else {
james@1007 202 FUNCTION_MSG("LargeSendOffload = %d\n", config_param->ParameterData.IntegerData);
james@1007 203 xi->frontend_gso_value = config_param->ParameterData.IntegerData;
james@1007 204 if (xi->frontend_gso_value > 61440) {
james@1007 205 xi->frontend_gso_value = 61440;
james@1007 206 FUNCTION_MSG(" (clipped to %d)\n", xi->frontend_gso_value);
james@1007 207 }
james@1007 208 if (!xi->frontend_sg_supported && xi->frontend_gso_value > PAGE_SIZE - MAX_PKT_HEADER_LENGTH) {
james@1007 209 /* without SG, GSO can be a maximum of PAGE_SIZE - MAX_PKT_HEADER_LENGTH */
james@1007 210 xi->frontend_gso_value = min(xi->frontend_gso_value, PAGE_SIZE - MAX_PKT_HEADER_LENGTH);
james@1007 211 FUNCTION_MSG(" (clipped to %d with sg disabled)\n", xi->frontend_gso_value);
james@1007 212 }
james@1007 213 }
james@1007 214 if (xi->frontend_sg_supported && ndis_os_minor_version < 1) {
james@1007 215 FUNCTION_MSG("No support for GSO with NDIS 6.0, disabled\n");
james@1007 216 xi->frontend_gso_value = 0;
james@1007 217 }
james@1007 218
james@1007 219 NdisInitUnicodeString(&config_param_name, L"LargeSendOffloadRxSplitMTU");
james@1007 220 NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
james@1007 221 if (!NT_SUCCESS(status)) {
james@1007 222 FUNCTION_MSG("Could not read LargeSendOffload value (%08x)\n", status);
james@1007 223 xi->frontend_gso_rx_split_type = RX_LSO_SPLIT_HALF;
james@1007 224 } else {
james@1007 225 FUNCTION_MSG("LargeSendOffloadRxSplitMTU = %d\n", config_param->ParameterData.IntegerData);
james@1007 226 switch (config_param->ParameterData.IntegerData) {
james@1007 227 case RX_LSO_SPLIT_MSS:
james@1007 228 case RX_LSO_SPLIT_HALF:
james@1007 229 case RX_LSO_SPLIT_NONE:
james@1007 230 xi->frontend_gso_rx_split_type = config_param->ParameterData.IntegerData;
james@1007 231 break;
james@1007 232 default:
james@1007 233 xi->frontend_gso_rx_split_type = RX_LSO_SPLIT_HALF;
james@1007 234 break;
james@1007 235 }
james@1007 236 }
james@1007 237
james@1007 238 NdisInitUnicodeString(&config_param_name, L"ChecksumOffload");
james@1007 239 NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
james@1007 240 if (!NT_SUCCESS(status)) {
james@1007 241 FUNCTION_MSG("Could not read ChecksumOffload value (%08x)\n", status);
james@1007 242 xi->frontend_csum_supported = TRUE;
james@1007 243 } else {
james@1007 244 FUNCTION_MSG("ChecksumOffload = %d\n", config_param->ParameterData.IntegerData);
james@1013 245 xi->frontend_csum_supported = (BOOLEAN)!!config_param->ParameterData.IntegerData;
james@1007 246 }
james@1007 247
james@1007 248 NdisInitUnicodeString(&config_param_name, L"MTU");
james@1007 249 NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
james@1007 250 if (!NT_SUCCESS(status)) {
james@1007 251 FUNCTION_MSG("Could not read MTU value (%08x)\n", status);
james@1007 252 xi->frontend_mtu_value = 1500;
james@1007 253 } else {
james@1007 254 FUNCTION_MSG("MTU = %d\n", config_param->ParameterData.IntegerData);
james@1007 255 xi->frontend_mtu_value = config_param->ParameterData.IntegerData;
james@1007 256 }
james@1007 257
james@1007 258 NdisReadNetworkAddress(&status, &network_address, &network_address_length, config_handle);
james@1007 259 if (!NT_SUCCESS(status) || network_address_length != ETH_ALEN || ((((PUCHAR)network_address)[0] & 0x03) != 0x02)) {
james@1007 260 FUNCTION_MSG("Could not read registry NetworkAddress value (%08x) or value is invalid\n", status);
james@1007 261 memset(xi->curr_mac_addr, 0, ETH_ALEN);
james@1007 262 } else {
james@1007 263 memcpy(xi->curr_mac_addr, network_address, ETH_ALEN);
james@1007 264 FUNCTION_MSG("Set MAC address from registry to %02X:%02X:%02X:%02X:%02X:%02X\n",
james@1007 265 xi->curr_mac_addr[0], xi->curr_mac_addr[1], xi->curr_mac_addr[2],
james@1007 266 xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5]);
james@1007 267 }
james@1007 268
james@1007 269 NdisCloseConfiguration(config_handle);
james@1007 270
james@1007 271 XenNet_Connect(xi, FALSE);
james@1007 272
james@1007 273 if (!xi->backend_sg_supported)
james@1007 274 xi->backend_gso_value = min(xi->backend_gso_value, PAGE_SIZE - MAX_PKT_HEADER_LENGTH);
james@1007 275
james@1007 276 xi->current_sg_supported = xi->frontend_sg_supported && xi->backend_sg_supported;
james@1007 277 xi->current_mtu_value = xi->frontend_mtu_value;
james@1007 278 xi->current_gso_rx_split_type = xi->frontend_gso_rx_split_type;
james@1007 279
james@1007 280 #if NTDDI_VERSION < NTDDI_VISTA
james@1007 281 /* these are set by OID for NDIS5 */
james@1007 282 xi->current_csum_supported = FALSE;
james@1007 283 xi->current_gso_value = 0;
james@1007 284 xi->config_max_pkt_size = xi->current_mtu_value + XN_HDR_SIZE;
james@1007 285 #else
james@1007 286 xi->current_csum_supported = xi->frontend_csum_supported && xi->backend_csum_supported;
james@1007 287 xi->current_gso_value = min(xi->backend_gso_value, xi->backend_gso_value);
james@1007 288 xi->config_max_pkt_size = max(xi->current_mtu_value + XN_HDR_SIZE, xi->current_gso_value + XN_HDR_SIZE);
james@1007 289 #endif
james@1007 290
james@1007 291 #if NTDDI_VERSION < NTDDI_VISTA
james@1007 292 NdisMSetAttributesEx(xi->adapter_handle, (NDIS_HANDLE)xi, 0, 0 /* the last zero is to give the next | something to | with */
james@1007 293 #ifdef NDIS51_MINIPORT
james@1007 294 |NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS
james@1007 295 #endif
james@1007 296 |NDIS_ATTRIBUTE_DESERIALIZE
james@1007 297 |NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK,
james@1007 298 NdisInterfaceInternal); /* PnpBus option doesn't exist... */
james@1007 299 #else
james@1007 300 registration_attributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
james@1007 301 registration_attributes.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
james@1007 302 registration_attributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
james@1007 303 registration_attributes.MiniportAdapterContext = xi;
james@1007 304 registration_attributes.AttributeFlags = 0;
james@1007 305 registration_attributes.AttributeFlags |= NDIS_MINIPORT_ATTRIBUTES_HARDWARE_DEVICE;
james@1007 306 registration_attributes.AttributeFlags |= NDIS_MINIPORT_ATTRIBUTES_SURPRISE_REMOVE_OK;
james@1007 307 registration_attributes.CheckForHangTimeInSeconds = 0; /* use default */
james@1007 308 registration_attributes.InterfaceType = NdisInterfacePNPBus;
james@1007 309 status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&registration_attributes);
james@1007 310 if (!NT_SUCCESS(status)) {
james@1007 311 FUNCTION_MSG("NdisMSetMiniportAttributes(registration) failed (%08x)\n", status);
james@1007 312 goto err;
james@1007 313 }
james@1007 314
james@1007 315 general_attributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
james@1007 316 general_attributes.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1; /* revision 2 is NDIS 6.2 */
james@1007 317 general_attributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
james@1007 318 general_attributes.Flags = 0;
james@1007 319 general_attributes.MediaType = NdisMedium802_3;
james@1007 320 general_attributes.PhysicalMediumType = NdisPhysicalMediumOther;
james@1007 321 general_attributes.MtuSize = xi->current_mtu_value;
james@1007 322 general_attributes.MaxXmitLinkSpeed = MAX_LINK_SPEED;
james@1007 323 general_attributes.XmitLinkSpeed = MAX_LINK_SPEED;
james@1007 324 general_attributes.MaxRcvLinkSpeed = MAX_LINK_SPEED;
james@1007 325 general_attributes.RcvLinkSpeed = MAX_LINK_SPEED;
james@1007 326 general_attributes.MediaConnectState = MediaConnectStateConnected;
james@1007 327 general_attributes.MediaDuplexState = MediaDuplexStateFull;
james@1007 328 general_attributes.LookaheadSize = xi->current_lookahead;
james@1007 329 general_attributes.PowerManagementCapabilities = NULL;
james@1007 330 general_attributes.MacOptions = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
james@1007 331 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
james@1007 332 NDIS_MAC_OPTION_NO_LOOPBACK;
james@1007 333 general_attributes.SupportedPacketFilters = SUPPORTED_PACKET_FILTERS;
james@1007 334 general_attributes.MaxMulticastListSize = MULTICAST_LIST_MAX_SIZE;
james@1007 335 general_attributes.MacAddressLength = 6;
james@1007 336 NdisMoveMemory(general_attributes.PermanentMacAddress, xi->perm_mac_addr, general_attributes.MacAddressLength);
james@1007 337 NdisMoveMemory(general_attributes.CurrentMacAddress, xi->curr_mac_addr, general_attributes.MacAddressLength);
james@1007 338 general_attributes.RecvScaleCapabilities = NULL; /* we do want to support this soon */
james@1007 339 general_attributes.AccessType = NET_IF_ACCESS_BROADCAST;
james@1007 340 general_attributes.DirectionType = NET_IF_DIRECTION_SENDRECEIVE;
james@1007 341 general_attributes.ConnectionType = NET_IF_CONNECTION_DEDICATED;
james@1007 342 general_attributes.IfType = IF_TYPE_ETHERNET_CSMACD;
james@1007 343 general_attributes.IfConnectorPresent = TRUE;
james@1007 344 general_attributes.SupportedStatistics = xi->stats.SupportedStatistics;
james@1007 345 general_attributes.SupportedPauseFunctions = NdisPauseFunctionsUnsupported;
james@1007 346 general_attributes.DataBackFillSize = 0; // see NdisRetreatNetBufferDataStart
james@1007 347 general_attributes.ContextBackFillSize = 0; // ?? NFI ??
james@1007 348
james@1007 349 for (i = 0; xennet_oids[i].oid; i++);
james@1007 350
james@1007 351 status = NdisAllocateMemoryWithTag((PVOID)&supported_oids, sizeof(NDIS_OID) * i, XENNET_POOL_TAG);
james@1007 352 if (!NT_SUCCESS(status)) {
james@1007 353 FUNCTION_MSG("NdisAllocateMemoryWithTag failed with 0x%x\n", status);
james@1007 354 status = NDIS_STATUS_RESOURCES;
james@1007 355 goto err;
james@1007 356 }
james@1007 357
james@1007 358 for (i = 0; xennet_oids[i].oid; i++) {
james@1007 359 supported_oids[i] = xennet_oids[i].oid;
james@1007 360 FUNCTION_MSG("Supporting %08x (%s) %s %d bytes\n", xennet_oids[i].oid, xennet_oids[i].oid_name, (xennet_oids[i].query_routine?(xennet_oids[i].set_routine?"get/set":"get only"):(xennet_oids[i].set_routine?"set only":"none")), xennet_oids[i].min_length);
james@1007 361 }
james@1007 362 general_attributes.SupportedOidList = supported_oids;
james@1007 363 general_attributes.SupportedOidListLength = sizeof(NDIS_OID) * i;
james@1007 364 general_attributes.AutoNegotiationFlags = NDIS_LINK_STATE_XMIT_LINK_SPEED_AUTO_NEGOTIATED
james@1007 365 | NDIS_LINK_STATE_RCV_LINK_SPEED_AUTO_NEGOTIATED
james@1007 366 | NDIS_LINK_STATE_DUPLEX_AUTO_NEGOTIATED;
james@1007 367 //general_attributes.PowerManagementCapabilitiesEx = NULL; // >= 6.20
james@1007 368 status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&general_attributes);
james@1007 369 if (!NT_SUCCESS(status)) {
james@1007 370 FUNCTION_MSG("NdisMSetMiniportAttributes(general) failed (%08x)\n", status);
james@1007 371 goto err;
james@1007 372 }
james@1007 373 NdisFreeMemory(supported_oids, 0, 0);
james@1007 374
james@1007 375 /* this is the initial offload state */
james@1007 376 RtlZeroMemory(&df_offload, sizeof(df_offload));
james@1007 377 df_offload.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
james@1007 378 df_offload.Header.Revision = NDIS_OFFLOAD_REVISION_1; // revision 2 does exist
james@1007 379 df_offload.Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;
james@1007 380 /* this is the supported offload state */
james@1007 381 RtlZeroMemory(&hw_offload, sizeof(hw_offload));
james@1007 382 hw_offload.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
james@1007 383 hw_offload.Header.Revision = NDIS_OFFLOAD_REVISION_1; // revision 2 does exist
james@1007 384 hw_offload.Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;
james@1007 385 if (xi->current_csum_supported)
james@1007 386 {
james@1007 387 df_offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
james@1007 388 df_offload.Checksum.IPv4Transmit.IpOptionsSupported = NDIS_OFFLOAD_SET_ON;
james@1007 389 df_offload.Checksum.IPv4Transmit.TcpOptionsSupported = NDIS_OFFLOAD_SET_ON;
james@1007 390 df_offload.Checksum.IPv4Transmit.TcpChecksum = NDIS_OFFLOAD_SET_ON;
james@1007 391 df_offload.Checksum.IPv4Transmit.UdpChecksum = NDIS_OFFLOAD_SET_ON;
james@1007 392 df_offload.Checksum.IPv4Transmit.IpChecksum = NDIS_OFFLOAD_SET_ON;
james@1007 393 df_offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
james@1007 394 df_offload.Checksum.IPv4Receive.IpOptionsSupported = NDIS_OFFLOAD_SET_ON;
james@1007 395 df_offload.Checksum.IPv4Receive.TcpOptionsSupported = NDIS_OFFLOAD_SET_ON;
james@1007 396 df_offload.Checksum.IPv4Receive.TcpChecksum = NDIS_OFFLOAD_SET_ON;
james@1007 397 df_offload.Checksum.IPv4Receive.UdpChecksum = NDIS_OFFLOAD_SET_ON;
james@1007 398 df_offload.Checksum.IPv4Receive.IpChecksum = NDIS_OFFLOAD_SET_ON;
james@1007 399 /* offload.Checksum.IPv6Transmit is not supported */
james@1007 400 /* offload.Checksum.IPv6Receive is not supported */
james@1007 401 hw_offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
james@1007 402 hw_offload.Checksum.IPv4Transmit.IpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;
james@1007 403 hw_offload.Checksum.IPv4Transmit.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;
james@1007 404 hw_offload.Checksum.IPv4Transmit.TcpChecksum = NDIS_OFFLOAD_SUPPORTED;
james@1007 405 hw_offload.Checksum.IPv4Transmit.UdpChecksum = NDIS_OFFLOAD_SUPPORTED;
james@1007 406 hw_offload.Checksum.IPv4Transmit.IpChecksum = NDIS_OFFLOAD_SUPPORTED;
james@1007 407 hw_offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
james@1007 408 hw_offload.Checksum.IPv4Receive.IpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;
james@1007 409 hw_offload.Checksum.IPv4Receive.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;
james@1007 410 hw_offload.Checksum.IPv4Receive.TcpChecksum = NDIS_OFFLOAD_SUPPORTED;
james@1007 411 hw_offload.Checksum.IPv4Receive.UdpChecksum = NDIS_OFFLOAD_SUPPORTED;
james@1007 412 hw_offload.Checksum.IPv4Receive.IpChecksum = NDIS_OFFLOAD_SUPPORTED;
james@1007 413 /* hw_offload.Checksum.IPv6Transmit is not supported */
james@1007 414 /* hw_offload.Checksum.IPv6Receive is not supported */
james@1007 415 }
james@1007 416 if (xi->current_gso_value)
james@1007 417 {
james@1007 418 hw_offload.LsoV1.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
james@1007 419 hw_offload.LsoV1.IPv4.MaxOffLoadSize = xi->current_gso_value;
james@1007 420 hw_offload.LsoV1.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
james@1007 421 hw_offload.LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */
james@1007 422 hw_offload.LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */
james@1007 423 hw_offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
james@1007 424 hw_offload.LsoV2.IPv4.MaxOffLoadSize = xi->current_gso_value;
james@1007 425 hw_offload.LsoV2.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
james@1007 426 /* hw_offload.LsoV2.IPv6 is not supported */
james@1007 427 df_offload.LsoV1.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
james@1007 428 df_offload.LsoV1.IPv4.MaxOffLoadSize = xi->current_gso_value;
james@1007 429 df_offload.LsoV1.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
james@1007 430 df_offload.LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */
james@1007 431 df_offload.LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */
james@1007 432 df_offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
james@1007 433 df_offload.LsoV2.IPv4.MaxOffLoadSize = xi->current_gso_value;
james@1007 434 df_offload.LsoV2.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
james@1007 435 /* df_offload.LsoV2.IPv6 is not supported */
james@1007 436 }
james@1007 437 /* hw_offload.IPsecV1 is not supported */
james@1007 438 /* hw_offload.IPsecV2 is not supported */
james@1007 439 /* df_offload.IPsecV1 is not supported */
james@1007 440 /* df_offload.IPsecV2 is not supported */
james@1007 441 hw_offload.Flags = 0;
james@1007 442 df_offload.Flags = 0;
james@1007 443
james@1007 444 RtlZeroMemory(&df_conn_offload, sizeof(df_conn_offload));
james@1007 445 df_conn_offload.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
james@1007 446 df_conn_offload.Header.Revision = NDIS_TCP_CONNECTION_OFFLOAD_REVISION_1;
james@1007 447 df_conn_offload.Header.Size = NDIS_SIZEOF_TCP_CONNECTION_OFFLOAD_REVISION_1;
james@1007 448
james@1007 449 RtlZeroMemory(&hw_conn_offload, sizeof(hw_conn_offload));
james@1007 450 hw_conn_offload.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
james@1007 451 hw_conn_offload.Header.Revision = NDIS_TCP_CONNECTION_OFFLOAD_REVISION_1;
james@1007 452 hw_conn_offload.Header.Size = NDIS_SIZEOF_TCP_CONNECTION_OFFLOAD_REVISION_1;
james@1007 453
james@1007 454 offload_attributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES;
james@1007 455 offload_attributes.Header.Revision = NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
james@1007 456 offload_attributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
james@1007 457 offload_attributes.DefaultOffloadConfiguration = &df_offload;
james@1007 458 offload_attributes.HardwareOffloadCapabilities = &hw_offload;
james@1007 459 offload_attributes.DefaultTcpConnectionOffloadConfiguration = &df_conn_offload;
james@1007 460 offload_attributes.TcpConnectionOffloadHardwareCapabilities = &hw_conn_offload;
james@1007 461 status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&offload_attributes);
james@1007 462 if (!NT_SUCCESS(status)) {
james@1007 463 FUNCTION_MSG("NdisMSetMiniportAttributes(offload) failed (%08x)\n", status);
james@1007 464 goto err;
james@1007 465 }
james@1007 466
james@1007 467 #if 0
james@1007 468 if (ndis_os_minor_version >= 1) {
james@1007 469 NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES hw_assist_attributes;
james@1007 470 NDIS_HD_SPLIT_ATTRIBUTES hd_split_attributes;
james@1007 471
james@1007 472 RtlZeroMemory(&hd_split_attributes, sizeof(hd_split_attributes));
james@1007 473 hd_split_attributes.Header.Type = NDIS_OBJECT_TYPE_HD_SPLIT_ATTRIBUTES;
james@1007 474 hd_split_attributes.Header.Revision = NDIS_HD_SPLIT_ATTRIBUTES_REVISION_1;
james@1007 475 hd_split_attributes.Header.Size = NDIS_SIZEOF_HD_SPLIT_ATTRIBUTES_REVISION_1;
james@1007 476 hd_split_attributes.HardwareCapabilities = NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT | NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV4_OPTIONS | NDIS_HD_SPLIT_CAPS_SUPPORTS_TCP_OPTIONS;
james@1007 477 hd_split_attributes.CurrentCapabilities = hd_split_attributes.HardwareCapabilities;
james@1007 478 /* the other members are set on output */
james@1007 479
james@1007 480 RtlZeroMemory(&hw_assist_attributes, sizeof(hw_assist_attributes));
james@1007 481 hw_assist_attributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES;
james@1007 482 hw_assist_attributes.Header.Revision = NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;
james@1007 483 hw_assist_attributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;
james@1007 484 hw_assist_attributes.HDSplitAttributes = &hd_split_attributes;
james@1007 485 status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&hw_assist_attributes);
james@1007 486 if (!NT_SUCCESS(status))
james@1007 487 {
james@1007 488 FUNCTION_MSG("NdisMSetMiniportAttributes(hw_assist) failed (%08x)\n", status);
james@1007 489 goto err;
james@1007 490 }
james@1007 491 FUNCTION_MSG("HW Split enabled\n");
james@1007 492 FUNCTION_MSG(" HDSplitFlags = %08x\n", hd_split_attributes.HDSplitFlags);
james@1007 493 FUNCTION_MSG(" BackfillSize = %d\n", hd_split_attributes.BackfillSize);
james@1007 494 FUNCTION_MSG(" MaxHeaderSize = %d\n", hd_split_attributes.MaxHeaderSize);
james@1007 495 //what about backfill here?
james@1007 496 }
james@1007 497 #endif
james@1007 498 #endif
james@1007 499 if (xi->device_state != DEVICE_STATE_INACTIVE)
james@1007 500 xi->device_state = DEVICE_STATE_ACTIVE;
james@1007 501 FUNCTION_EXIT();
james@1007 502 return NDIS_STATUS_SUCCESS;
james@1007 503
james@1007 504 err:
james@1007 505 if (xi) {
james@1007 506 NdisFreeMemory(xi, 0, 0);
james@1007 507 }
james@1007 508 FUNCTION_EXIT_STATUS(status);
james@1007 509
james@1007 510 return status;
james@1007 511 }
james@1007 512
james@1007 513 #if NTDDI_VERSION < NTDDI_VISTA
james@1007 514 static VOID
james@1007 515 XenNet_PnPEventNotify(NDIS_HANDLE adapter_context, NDIS_DEVICE_PNP_EVENT pnp_event, PVOID information_buffer, ULONG information_buffer_length) {
james@1007 516 UNREFERENCED_PARAMETER(information_buffer);
james@1007 517 UNREFERENCED_PARAMETER(information_buffer_length);
james@1007 518 UNREFERENCED_PARAMETER(adapter_context);
james@1007 519
james@1007 520 FUNCTION_ENTER();
james@1007 521 switch (pnp_event)
james@1007 522 {
james@1007 523 case NdisDevicePnPEventSurpriseRemoved:
james@1007 524 FUNCTION_MSG("NdisDevicePnPEventSurpriseRemoved\n");
james@1007 525 break;
james@1007 526 case NdisDevicePnPEventPowerProfileChanged :
james@1007 527 FUNCTION_MSG("NdisDevicePnPEventPowerProfileChanged\n");
james@1007 528 break;
james@1007 529 default:
james@1007 530 FUNCTION_MSG("NdisDevicePnPEvent%d\n", pnp_event);
james@1007 531 break;
james@1007 532 }
james@1007 533 FUNCTION_EXIT();
james@1007 534 }
james@1007 535 #else
james@1007 536 static VOID
james@1007 537 XenNet_DevicePnPEventNotify(NDIS_HANDLE adapter_context, PNET_DEVICE_PNP_EVENT pnp_event) {
james@1007 538 UNREFERENCED_PARAMETER(adapter_context);
james@1007 539
james@1007 540 FUNCTION_ENTER();
james@1007 541 switch (pnp_event->DevicePnPEvent)
james@1007 542 {
james@1007 543 case NdisDevicePnPEventSurpriseRemoved:
james@1007 544 FUNCTION_MSG("NdisDevicePnPEventSurpriseRemoved\n");
james@1007 545 break;
james@1007 546 case NdisDevicePnPEventPowerProfileChanged :
james@1007 547 FUNCTION_MSG("NdisDevicePnPEventPowerProfileChanged\n");
james@1007 548 break;
james@1007 549 default:
james@1007 550 FUNCTION_MSG("NdisDevicePnPEvent%d\n", pnp_event->DevicePnPEvent);
james@1007 551 break;
james@1007 552 }
james@1007 553 FUNCTION_EXIT();
james@1007 554 }
james@1007 555 #endif
james@1007 556
james@1007 557 /* called at <= HIGH_IRQL, or PASSIVE_LEVEL, depending on shutdown_action */
james@1007 558 static VOID
james@1007 559 #if NTDDI_VERSION < NTDDI_VISTA
james@1007 560 XenNet_Shutdown(NDIS_HANDLE adapter_context) {
james@1007 561 #else
james@1007 562 XenNet_Shutdown(NDIS_HANDLE adapter_context, NDIS_SHUTDOWN_ACTION shutdown_action) {
james@1007 563 UNREFERENCED_PARAMETER(shutdown_action);
james@1007 564 #endif
james@1007 565 UNREFERENCED_PARAMETER(adapter_context);
james@1007 566 FUNCTION_ENTER();
james@1007 567 FUNCTION_EXIT();
james@1007 568 }
james@1007 569
james@1007 570 static BOOLEAN
james@1007 571 XenNet_CheckForHang(NDIS_HANDLE adapter_context)
james@1007 572 {
james@1007 573 UNREFERENCED_PARAMETER(adapter_context);
james@1007 574
james@1007 575 //FUNCTION_ENTER();
james@1007 576 //FUNCTION_EXIT();
james@1007 577 return FALSE;
james@1007 578 }
james@1007 579
james@1007 580 /* Opposite of XenNet_Init */
james@1007 581 static VOID
james@1007 582 #if NTDDI_VERSION < NTDDI_VISTA
james@1007 583 XenNet_Halt(NDIS_HANDLE adapter_context) {
james@1007 584 #else
james@1007 585 XenNet_Halt(NDIS_HANDLE adapter_context, NDIS_HALT_ACTION halt_action) {
james@1007 586 #endif
james@1007 587 struct xennet_info *xi = adapter_context;
james@1007 588 #if NTDDI_VERSION < NTDDI_VISTA
james@1007 589 #else
james@1007 590 UNREFERENCED_PARAMETER(halt_action);
james@1007 591 #endif
james@1007 592 FUNCTION_ENTER();
james@1007 593 XenNet_Disconnect(xi, FALSE);
james@1007 594 NdisFreeMemory(xi, 0, 0);
james@1007 595
james@1007 596 FUNCTION_EXIT();
james@1007 597 }
james@1007 598
james@1007 599 static NDIS_STATUS
james@1007 600 XenNet_Reset(NDIS_HANDLE adapter_context, PBOOLEAN addressing_reset)
james@1007 601 {
james@1007 602 UNREFERENCED_PARAMETER(adapter_context);
james@1007 603
james@1007 604 FUNCTION_ENTER();
james@1007 605 *addressing_reset = FALSE;
james@1007 606 FUNCTION_EXIT();
james@1007 607 return NDIS_STATUS_SUCCESS;
james@1007 608 }
james@1007 609
james@1007 610 #if NTDDI_VERSION < NTDDI_VISTA
james@1007 611 #else
james@1007 612 /* called at PASSIVE_LEVEL */
james@1007 613 static NDIS_STATUS
james@1007 614 XenNet_Pause(NDIS_HANDLE adapter_context, PNDIS_MINIPORT_PAUSE_PARAMETERS pause_parameters)
james@1007 615 {
james@1007 616 UNREFERENCED_PARAMETER(adapter_context);
james@1007 617 UNREFERENCED_PARAMETER(pause_parameters);
james@1007 618 FUNCTION_ENTER();
james@1007 619 FUNCTION_EXIT();
james@1007 620 return STATUS_SUCCESS;
james@1007 621 }
james@1007 622
james@1007 623 /* called at PASSIVE_LEVEL */
james@1007 624 static NDIS_STATUS
james@1007 625 XenNet_Restart(NDIS_HANDLE adapter_context, PNDIS_MINIPORT_RESTART_PARAMETERS restart_parameters)
james@1007 626 {
james@1007 627 UNREFERENCED_PARAMETER(adapter_context);
james@1007 628 UNREFERENCED_PARAMETER(restart_parameters);
james@1007 629 FUNCTION_ENTER();
james@1007 630 FUNCTION_EXIT();
james@1007 631 return STATUS_SUCCESS;
james@1007 632 }
james@1007 633
james@1007 634 static VOID
james@1007 635 XenNet_Unload(PDRIVER_OBJECT driver_object)
james@1007 636 {
james@1007 637 UNREFERENCED_PARAMETER(driver_object);
james@1007 638 FUNCTION_ENTER();
james@1007 639 NdisMDeregisterMiniportDriver(driver_handle);
james@1007 640 FUNCTION_EXIT();
james@1007 641 }
james@1007 642
james@1007 643 static NDIS_STATUS
james@1007 644 XenNet_SetOptions(NDIS_HANDLE driver_handle, NDIS_HANDLE driver_context)
james@1007 645 {
james@1007 646 UNREFERENCED_PARAMETER(driver_handle);
james@1007 647 UNREFERENCED_PARAMETER(driver_context);
james@1007 648 FUNCTION_ENTER();
james@1007 649 FUNCTION_EXIT();
james@1007 650 return STATUS_SUCCESS;
james@1007 651 }
james@1007 652 #endif
james@1007 653
james@1007 654 NTSTATUS
james@1007 655 DriverEntry(PDRIVER_OBJECT driver_object, PUNICODE_STRING registry_path)
james@1007 656 {
james@1007 657 NTSTATUS status;
james@1007 658 ULONG ndis_version;
james@1007 659 #if NTDDI_VERSION < NTDDI_VISTA
james@1007 660 NDIS_HANDLE ndis_wrapper_handle = NULL;
james@1007 661 NDIS_MINIPORT_CHARACTERISTICS mini_chars;
james@1007 662 #else
james@1007 663 NDIS_MINIPORT_DRIVER_CHARACTERISTICS mini_chars;
james@1007 664 #endif
james@1007 665
james@1007 666 FUNCTION_ENTER();
james@1007 667
james@1007 668 NdisZeroMemory(&mini_chars, sizeof(mini_chars));
james@1007 669
james@1007 670 ndis_version = NdisGetVersion();
james@1007 671
james@1013 672 ndis_os_major_version = (USHORT)(ndis_version >> 16);
james@1013 673 ndis_os_minor_version = (USHORT)(ndis_version & 0xFFFF);
james@1007 674
james@1007 675 FUNCTION_MSG("Driver MajorNdisVersion = %d, Driver MinorNdisVersion = %d\n", NDIS_MINIPORT_MAJOR_VERSION, NDIS_MINIPORT_MINOR_VERSION);
james@1007 676 FUNCTION_MSG("Windows MajorNdisVersion = %d, Windows MinorNdisVersion = %d\n", ndis_os_major_version, ndis_os_minor_version);
james@1007 677
james@1007 678 #if NTDDI_VERSION < NTDDI_VISTA
james@1007 679 NdisMInitializeWrapper(&ndis_wrapper_handle, driver_object, registry_path, NULL);
james@1007 680 if (!ndis_wrapper_handle) {
james@1007 681 FUNCTION_MSG("NdisMInitializeWrapper failed\n");
james@1007 682 return NDIS_STATUS_FAILURE;
james@1007 683 }
james@1007 684
james@1007 685 mini_chars.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION;
james@1007 686 mini_chars.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION;
james@1007 687 mini_chars.HaltHandler = XenNet_Halt;
james@1007 688 mini_chars.InitializeHandler = XenNet_Init;
james@1007 689 mini_chars.QueryInformationHandler = XenNet_QueryInformation;
james@1007 690 mini_chars.ResetHandler = XenNet_Reset;
james@1007 691 mini_chars.SetInformationHandler = XenNet_SetInformation;
james@1007 692 mini_chars.ReturnPacketHandler = XenNet_ReturnPacket;
james@1007 693 mini_chars.SendPacketsHandler = XenNet_SendPackets;
james@1007 694 #ifdef NDIS51_MINIPORT
james@1007 695 mini_chars.PnPEventNotifyHandler = XenNet_PnPEventNotify;
james@1007 696 mini_chars.AdapterShutdownHandler = XenNet_Shutdown;
james@1007 697 #endif
james@1007 698 status = NdisMRegisterMiniport(ndis_wrapper_handle, &mini_chars, sizeof(mini_chars));
james@1007 699 if (!NT_SUCCESS(status)) {
james@1007 700 FUNCTION_MSG("NdisMRegisterMiniport failed, status = 0x%x\n", status);
james@1007 701 NdisTerminateWrapper(ndis_wrapper_handle, NULL);
james@1007 702 return status;
james@1007 703 }
james@1007 704 #else
james@1007 705 mini_chars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS;
james@1007 706
james@1007 707 if (ndis_os_minor_version < 1) {
james@1007 708 mini_chars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
james@1007 709 mini_chars.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
james@1007 710
james@1007 711 mini_chars.MajorNdisVersion = 6;
james@1007 712 mini_chars.MinorNdisVersion = 0;
james@1007 713 } else {
james@1007 714 mini_chars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
james@1007 715 mini_chars.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
james@1007 716 mini_chars.MajorNdisVersion = 6;
james@1007 717 mini_chars.MinorNdisVersion = 1;
james@1007 718 }
james@1007 719 mini_chars.MajorDriverVersion = VENDOR_DRIVER_VERSION_MAJOR;
james@1007 720 mini_chars.MinorDriverVersion = VENDOR_DRIVER_VERSION_MINOR;
james@1007 721
james@1007 722 mini_chars.Flags = NDIS_WDM_DRIVER;
james@1007 723
james@1007 724 mini_chars.SetOptionsHandler = XenNet_SetOptions;
james@1007 725 mini_chars.InitializeHandlerEx = XenNet_Initialize;
james@1007 726 mini_chars.HaltHandlerEx = XenNet_Halt;
james@1007 727 mini_chars.UnloadHandler = XenNet_Unload;
james@1007 728 mini_chars.PauseHandler = XenNet_Pause;
james@1007 729 mini_chars.RestartHandler = XenNet_Restart;
james@1007 730 mini_chars.CheckForHangHandlerEx = XenNet_CheckForHang;
james@1007 731 mini_chars.ResetHandlerEx = XenNet_Reset;
james@1007 732 mini_chars.DevicePnPEventNotifyHandler = XenNet_DevicePnPEventNotify;
james@1007 733 mini_chars.ShutdownHandlerEx = XenNet_Shutdown;
james@1007 734
james@1007 735 mini_chars.OidRequestHandler = XenNet_OidRequest;
james@1007 736 mini_chars.CancelOidRequestHandler = XenNet_CancelOidRequest;
james@1007 737 if (ndis_os_minor_version >= 1) {
james@1007 738 mini_chars.DirectOidRequestHandler = NULL;
james@1007 739 mini_chars.CancelDirectOidRequestHandler = NULL;
james@1007 740 }
james@1007 741
james@1007 742 mini_chars.SendNetBufferListsHandler = XenNet_SendNetBufferLists;
james@1011 743 mini_chars.CancelSendHandler = XenNet_CancelSend;
james@1007 744
james@1007 745 mini_chars.ReturnNetBufferListsHandler = XenNet_ReturnNetBufferLists;
james@1007 746
james@1007 747 status = NdisMRegisterMiniportDriver(driver_object, registry_path, NULL, &mini_chars, &driver_handle);
james@1007 748 if (!NT_SUCCESS(status)) {
james@1007 749 FUNCTION_MSG("NdisMRegisterMiniportDriver failed, status = 0x%x\n", status);
james@1007 750 return status;
james@1007 751 }
james@1007 752 #endif
james@1007 753 FUNCTION_EXIT();
james@1007 754
james@1007 755 return status;
james@1007 756 }