win-pvdrivers

changeset 1007:4cda50fe71d5

merge ndis5 and ndis6 code in xennet
author James Harper <james.harper@bendigoit.com.au>
date Sun Feb 10 23:14:05 2013 +1100 (2013-02-10)
parents 9fb8690938b3
children 2b8784b1a034
files xennet/sources xennet/xennet.c xennet/xennet.h xennet/xennet5.c xennet/xennet5.h xennet/xennet5_common.c xennet/xennet5_oid.c xennet/xennet5_rx.c xennet/xennet5_tx.c xennet/xennet6.c xennet/xennet6.h xennet/xennet6_common.c xennet/xennet6_oid.c xennet/xennet6_rx.c xennet/xennet6_tx.c xennet/xennet_common.c xennet/xennet_oid.c xennet/xennet_rx.c xennet/xennet_tx.c
line diff
     1.1 --- a/xennet/sources	Sun Feb 10 23:12:03 2013 +1100
     1.2 +++ b/xennet/sources	Sun Feb 10 23:14:05 2013 +1100
     1.3 @@ -17,5 +17,5 @@ C_DEFINES=$(C_DEFINES) -D_GPLPV_NDIS5
     1.4  !ELSE
     1.5  C_DEFINES=$(C_DEFINES) -D_GPLPV_NDIS6
     1.6  !ENDIF
     1.7 -NTTARGETFILES=$(NTTARGETFILES) $(OBJ_PATH)\$(O)\$(INF_NAME).inf
     1.8 +NTTARGETFILE0=$(NTTARGETFILES) $(OBJ_PATH)\$(O)\$(INF_NAME).inf
     1.9  SOURCES=xennet.rc xennet.c xennet_tx.c xennet_rx.c xennet_oid.c xennet_common.c
     2.1 --- a/xennet/xennet.c	Sun Feb 10 23:12:03 2013 +1100
     2.2 +++ b/xennet/xennet.c	Sun Feb 10 23:14:05 2013 +1100
     2.3 @@ -1,5 +1,756 @@
     2.4 -#ifdef _GPLPV_NDIS5
     2.5 -#include "xennet5.c"
     2.6 +/*
     2.7 +PV Net Driver for Windows Xen HVM Domains
     2.8 +Copyright (C) 2007 James Harper
     2.9 +Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
    2.10 +
    2.11 +This program is free software; you can redistribute it and/or
    2.12 +modify it under the terms of the GNU General Public License
    2.13 +as published by the Free Software Foundation; either version 2
    2.14 +of the License, or (at your option) any later version.
    2.15 +
    2.16 +This program is distributed in the hope that it will be useful,
    2.17 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.18 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.19 +GNU General Public License for more details.
    2.20 +
    2.21 +You should have received a copy of the GNU General Public License
    2.22 +along with this program; if not, write to the Free Software
    2.23 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    2.24 +*/
    2.25 +
    2.26 +#include <stdlib.h>
    2.27 +#include <io/xenbus.h>
    2.28 +#include "xennet.h"
    2.29 +
    2.30 +/* Not really necessary but keeps PREfast happy */
    2.31 +DRIVER_INITIALIZE DriverEntry;
    2.32 +#if (VER_PRODUCTBUILD >= 7600)
    2.33 +static KDEFERRED_ROUTINE XenNet_RxTxDpc;
    2.34 +#endif
    2.35 +VOID XenNet_DeviceCallback(PVOID context, ULONG callback_type, PVOID value);
    2.36 +
    2.37 +#pragma NDIS_INIT_FUNCTION(DriverEntry)
    2.38 +
    2.39 +NDIS_HANDLE driver_handle = NULL;
    2.40 +
    2.41 +USHORT ndis_os_major_version = 0;
    2.42 +USHORT ndis_os_minor_version = 0;
    2.43 +
    2.44 +static VOID
    2.45 +XenNet_RxTxDpc(PKDPC dpc, PVOID context, PVOID arg1, PVOID arg2)
    2.46 +{
    2.47 +  struct xennet_info *xi = context;
    2.48 +  BOOLEAN dont_set_event;
    2.49 +
    2.50 +  UNREFERENCED_PARAMETER(dpc);
    2.51 +  UNREFERENCED_PARAMETER(arg1);
    2.52 +  UNREFERENCED_PARAMETER(arg2);
    2.53 +
    2.54 +  //FUNCTION_ENTER();
    2.55 +  /* 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 */
    2.56 +  dont_set_event = XenNet_RxBufferCheck(xi);
    2.57 +  XenNet_TxBufferGC(xi, dont_set_event);
    2.58 +  //FUNCTION_EXIT();
    2.59 +} 
    2.60 +
    2.61 +// Called at PASSIVE_LEVEL
    2.62 +#if NTDDI_VERSION < NTDDI_VISTA
    2.63 +static NDIS_STATUS
    2.64 +XenNet_Init(PNDIS_STATUS open_error_status, PUINT SelectedMediumIndex, PNDIS_MEDIUM MediumArray, UINT MediumArraySize, NDIS_HANDLE adapter_handle, NDIS_HANDLE WrapperConfigurationContext)
    2.65  #else
    2.66 -#include "xennet6.c"
    2.67 +static NDIS_STATUS
    2.68 +XenNet_Initialize(NDIS_HANDLE adapter_handle, NDIS_HANDLE driver_context, PNDIS_MINIPORT_INIT_PARAMETERS init_parameters)
    2.69  #endif
    2.70 +{
    2.71 +  NDIS_STATUS status;
    2.72 +  struct xennet_info *xi = NULL;
    2.73 +  NDIS_HANDLE config_handle;
    2.74 +  PNDIS_CONFIGURATION_PARAMETER config_param;
    2.75 +  NDIS_STRING config_param_name;
    2.76 +  ULONG i;
    2.77 +  //ULONG length;
    2.78 +  PVOID network_address;
    2.79 +  UINT network_address_length;
    2.80 +  #if NTDDI_VERSION < NTDDI_VISTA
    2.81 +  #else
    2.82 +  NDIS_CONFIGURATION_OBJECT config_object;
    2.83 +  NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES registration_attributes;
    2.84 +  NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES general_attributes;
    2.85 +  NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES offload_attributes;
    2.86 +  NDIS_OFFLOAD df_offload, hw_offload;
    2.87 +  NDIS_TCP_CONNECTION_OFFLOAD df_conn_offload, hw_conn_offload;
    2.88 +  NDIS_OID *supported_oids;
    2.89 +  #endif
    2.90 +
    2.91 +  #if NTDDI_VERSION < NTDDI_VISTA
    2.92 +  UNREFERENCED_PARAMETER(open_error_status);
    2.93 +  #else
    2.94 +  UNREFERENCED_PARAMETER(driver_context);
    2.95 +  UNREFERENCED_PARAMETER(init_parameters);
    2.96 +  #endif
    2.97 +
    2.98 +  FUNCTION_ENTER();
    2.99 +
   2.100 +  #if NTDDI_VERSION < NTDDI_VISTA
   2.101 +  for (i = 0; i < MediumArraySize; i++) {
   2.102 +    if (MediumArray[i] == NdisMedium802_3) {
   2.103 +      break;
   2.104 +    }
   2.105 +  }
   2.106 +  if (i == MediumArraySize) {
   2.107 +    FUNCTION_MSG("NIC_MEDIA_TYPE not in MediumArray\n");
   2.108 +    return NDIS_STATUS_UNSUPPORTED_MEDIA;
   2.109 +  }
   2.110 +  *SelectedMediumIndex = i;
   2.111 +  #endif
   2.112 +  /* Alloc memory for adapter private info */
   2.113 +  status = NdisAllocateMemoryWithTag((PVOID)&xi, sizeof(*xi), XENNET_POOL_TAG);
   2.114 +  if (!NT_SUCCESS(status))  {
   2.115 +    FUNCTION_MSG("NdisAllocateMemoryWithTag failed with 0x%x\n", status);
   2.116 +    status = NDIS_STATUS_RESOURCES;
   2.117 +    goto err;
   2.118 +  }
   2.119 +  RtlZeroMemory(xi, sizeof(*xi));
   2.120 +  xi->adapter_handle = adapter_handle;
   2.121 +  xi->device_state = DEVICE_STATE_INITIALISING;
   2.122 +  NdisMGetDeviceProperty(xi->adapter_handle, &xi->pdo, &xi->fdo,
   2.123 +    &xi->lower_do, NULL, NULL);
   2.124 +  KeInitializeEvent(&xi->backend_event, SynchronizationEvent, FALSE);
   2.125 +
   2.126 +  #if NTDDI_VERSION < NTDDI_VISTA
   2.127 +  #endif
   2.128 +  xi->rx_target     = RX_DFL_MIN_TARGET;
   2.129 +  xi->rx_min_target = RX_DFL_MIN_TARGET;
   2.130 +  xi->rx_max_target = RX_MAX_TARGET;
   2.131 +  
   2.132 +  xi->multicast_list_size = 0;
   2.133 +  xi->current_lookahead = MIN_LOOKAHEAD_LENGTH;
   2.134 +
   2.135 +  #if NTDDI_VERSION < NTDDI_VISTA
   2.136 +  #else
   2.137 +  xi->stats.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
   2.138 +  xi->stats.Header.Revision = NDIS_STATISTICS_INFO_REVISION_1;
   2.139 +  xi->stats.Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1;
   2.140 +  xi->stats.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED
   2.141 +    | NDIS_STATISTICS_RCV_OK_SUPPORTED
   2.142 +    | NDIS_STATISTICS_XMIT_ERROR_SUPPORTED
   2.143 +    | NDIS_STATISTICS_RCV_ERROR_SUPPORTED
   2.144 +    | NDIS_STATISTICS_RCV_NO_BUFFER_SUPPORTED
   2.145 +    | NDIS_STATISTICS_DIRECTED_BYTES_XMIT_SUPPORTED
   2.146 +    | NDIS_STATISTICS_DIRECTED_FRAMES_XMIT_SUPPORTED
   2.147 +    | NDIS_STATISTICS_MULTICAST_BYTES_XMIT_SUPPORTED
   2.148 +    | NDIS_STATISTICS_MULTICAST_FRAMES_XMIT_SUPPORTED
   2.149 +    | NDIS_STATISTICS_BROADCAST_BYTES_XMIT_SUPPORTED
   2.150 +    | NDIS_STATISTICS_BROADCAST_FRAMES_XMIT_SUPPORTED
   2.151 +    | NDIS_STATISTICS_DIRECTED_BYTES_RCV_SUPPORTED
   2.152 +    | NDIS_STATISTICS_DIRECTED_FRAMES_RCV_SUPPORTED
   2.153 +    | NDIS_STATISTICS_MULTICAST_BYTES_RCV_SUPPORTED
   2.154 +    | NDIS_STATISTICS_MULTICAST_FRAMES_RCV_SUPPORTED
   2.155 +    | NDIS_STATISTICS_BROADCAST_BYTES_RCV_SUPPORTED
   2.156 +    | NDIS_STATISTICS_BROADCAST_FRAMES_RCV_SUPPORTED
   2.157 +    | NDIS_STATISTICS_RCV_CRC_ERROR_SUPPORTED
   2.158 +    | NDIS_STATISTICS_TRANSMIT_QUEUE_LENGTH_SUPPORTED
   2.159 +    | NDIS_STATISTICS_BYTES_RCV_SUPPORTED
   2.160 +    | NDIS_STATISTICS_BYTES_XMIT_SUPPORTED
   2.161 +    | NDIS_STATISTICS_RCV_DISCARDS_SUPPORTED
   2.162 +    | NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED
   2.163 +    | NDIS_STATISTICS_XMIT_DISCARDS_SUPPORTED;
   2.164 +  #endif
   2.165 +  
   2.166 +  KeInitializeDpc(&xi->rxtx_dpc, XenNet_RxTxDpc, xi);
   2.167 +
   2.168 +  xi->packet_filter = 0;
   2.169 +
   2.170 +  #if NTDDI_VERSION < NTDDI_VISTA
   2.171 +  NdisOpenConfiguration(&status, &config_handle, WrapperConfigurationContext);
   2.172 +  #else
   2.173 +  config_object.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT);
   2.174 +  config_object.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
   2.175 +  config_object.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
   2.176 +  config_object.NdisHandle = xi->adapter_handle;
   2.177 +  config_object.Flags = 0;
   2.178 +
   2.179 +  status = NdisOpenConfigurationEx(&config_object, &config_handle);
   2.180 +  #endif
   2.181 +  if (!NT_SUCCESS(status)) {
   2.182 +    FUNCTION_MSG("Could not open config in registry (%08x)\n", status);
   2.183 +    status = NDIS_STATUS_RESOURCES;
   2.184 +    goto err;
   2.185 +  }
   2.186 +
   2.187 +  NdisInitUnicodeString(&config_param_name, L"ScatterGather");
   2.188 +  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
   2.189 +  if (!NT_SUCCESS(status))
   2.190 +  {
   2.191 +    FUNCTION_MSG("Could not read ScatterGather value (%08x)\n", status);
   2.192 +    xi->frontend_sg_supported = TRUE;
   2.193 +  } else {
   2.194 +    FUNCTION_MSG("ScatterGather = %d\n", config_param->ParameterData.IntegerData);
   2.195 +    xi->frontend_sg_supported = !!config_param->ParameterData.IntegerData;
   2.196 +  }
   2.197 +  if (xi->frontend_sg_supported && ndis_os_minor_version < 1) {
   2.198 +    FUNCTION_MSG("No support for SG with NDIS 6.0, disabled\n");
   2.199 +    xi->frontend_sg_supported = FALSE;
   2.200 +  }
   2.201 +  
   2.202 +  NdisInitUnicodeString(&config_param_name, L"LargeSendOffload");
   2.203 +  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
   2.204 +  if (!NT_SUCCESS(status)) {
   2.205 +    FUNCTION_MSG("Could not read LargeSendOffload value (%08x)\n", status);
   2.206 +    xi->frontend_gso_value = 0;
   2.207 +  } else {
   2.208 +    FUNCTION_MSG("LargeSendOffload = %d\n", config_param->ParameterData.IntegerData);
   2.209 +    xi->frontend_gso_value = config_param->ParameterData.IntegerData;
   2.210 +    if (xi->frontend_gso_value > 61440) {
   2.211 +      xi->frontend_gso_value = 61440;
   2.212 +      FUNCTION_MSG("  (clipped to %d)\n", xi->frontend_gso_value);
   2.213 +    }
   2.214 +    if (!xi->frontend_sg_supported && xi->frontend_gso_value > PAGE_SIZE - MAX_PKT_HEADER_LENGTH) {
   2.215 +      /* without SG, GSO can be a maximum of PAGE_SIZE - MAX_PKT_HEADER_LENGTH */
   2.216 +      xi->frontend_gso_value = min(xi->frontend_gso_value, PAGE_SIZE - MAX_PKT_HEADER_LENGTH);
   2.217 +      FUNCTION_MSG("  (clipped to %d with sg disabled)\n", xi->frontend_gso_value);
   2.218 +    }
   2.219 +  }
   2.220 +  if (xi->frontend_sg_supported && ndis_os_minor_version < 1) {
   2.221 +    FUNCTION_MSG("No support for GSO with NDIS 6.0, disabled\n");
   2.222 +    xi->frontend_gso_value = 0;
   2.223 +  }
   2.224 +
   2.225 +  NdisInitUnicodeString(&config_param_name, L"LargeSendOffloadRxSplitMTU");
   2.226 +  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
   2.227 +  if (!NT_SUCCESS(status)) {
   2.228 +    FUNCTION_MSG("Could not read LargeSendOffload value (%08x)\n", status);
   2.229 +    xi->frontend_gso_rx_split_type = RX_LSO_SPLIT_HALF;
   2.230 +  } else {
   2.231 +    FUNCTION_MSG("LargeSendOffloadRxSplitMTU = %d\n", config_param->ParameterData.IntegerData);
   2.232 +    switch (config_param->ParameterData.IntegerData) {
   2.233 +    case RX_LSO_SPLIT_MSS:
   2.234 +    case RX_LSO_SPLIT_HALF:
   2.235 +    case RX_LSO_SPLIT_NONE:
   2.236 +      xi->frontend_gso_rx_split_type = config_param->ParameterData.IntegerData;
   2.237 +      break;
   2.238 +    default:
   2.239 +      xi->frontend_gso_rx_split_type = RX_LSO_SPLIT_HALF;
   2.240 +      break;
   2.241 +    }
   2.242 +  }
   2.243 +
   2.244 +  NdisInitUnicodeString(&config_param_name, L"ChecksumOffload");
   2.245 +  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
   2.246 +  if (!NT_SUCCESS(status)) {
   2.247 +    FUNCTION_MSG("Could not read ChecksumOffload value (%08x)\n", status);
   2.248 +    xi->frontend_csum_supported = TRUE;
   2.249 +  } else {
   2.250 +    FUNCTION_MSG("ChecksumOffload = %d\n", config_param->ParameterData.IntegerData);
   2.251 +    xi->frontend_csum_supported = !!config_param->ParameterData.IntegerData;
   2.252 +  }
   2.253 +
   2.254 +  NdisInitUnicodeString(&config_param_name, L"MTU");
   2.255 +  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);  
   2.256 +  if (!NT_SUCCESS(status)) {
   2.257 +    FUNCTION_MSG("Could not read MTU value (%08x)\n", status);
   2.258 +    xi->frontend_mtu_value = 1500;
   2.259 +  } else {
   2.260 +    FUNCTION_MSG("MTU = %d\n", config_param->ParameterData.IntegerData);
   2.261 +    xi->frontend_mtu_value = config_param->ParameterData.IntegerData;
   2.262 +  }
   2.263 +  
   2.264 +  NdisReadNetworkAddress(&status, &network_address, &network_address_length, config_handle);
   2.265 +  if (!NT_SUCCESS(status) || network_address_length != ETH_ALEN || ((((PUCHAR)network_address)[0] & 0x03) != 0x02)) {
   2.266 +    FUNCTION_MSG("Could not read registry NetworkAddress value (%08x) or value is invalid\n", status);
   2.267 +    memset(xi->curr_mac_addr, 0, ETH_ALEN);
   2.268 +  } else {
   2.269 +    memcpy(xi->curr_mac_addr, network_address, ETH_ALEN);
   2.270 +    FUNCTION_MSG("Set MAC address from registry to %02X:%02X:%02X:%02X:%02X:%02X\n",
   2.271 +      xi->curr_mac_addr[0], xi->curr_mac_addr[1], xi->curr_mac_addr[2], 
   2.272 +      xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5]);
   2.273 +  }
   2.274 +
   2.275 +  NdisCloseConfiguration(config_handle);
   2.276 +
   2.277 +  XenNet_Connect(xi, FALSE);
   2.278 +
   2.279 +  if (!xi->backend_sg_supported)
   2.280 +    xi->backend_gso_value = min(xi->backend_gso_value, PAGE_SIZE - MAX_PKT_HEADER_LENGTH);
   2.281 +
   2.282 +  xi->current_sg_supported = xi->frontend_sg_supported && xi->backend_sg_supported;
   2.283 +  xi->current_mtu_value = xi->frontend_mtu_value;
   2.284 +  xi->current_gso_rx_split_type = xi->frontend_gso_rx_split_type;
   2.285 +  
   2.286 +  #if NTDDI_VERSION < NTDDI_VISTA
   2.287 +  /* these are set by OID for NDIS5 */
   2.288 +  xi->current_csum_supported = FALSE;
   2.289 +  xi->current_gso_value = 0;
   2.290 +  xi->config_max_pkt_size = xi->current_mtu_value + XN_HDR_SIZE;
   2.291 +  #else
   2.292 +  xi->current_csum_supported = xi->frontend_csum_supported && xi->backend_csum_supported;
   2.293 +  xi->current_gso_value = min(xi->backend_gso_value, xi->backend_gso_value);
   2.294 +  xi->config_max_pkt_size = max(xi->current_mtu_value + XN_HDR_SIZE, xi->current_gso_value + XN_HDR_SIZE);
   2.295 +  #endif
   2.296 +    
   2.297 +  #if NTDDI_VERSION < NTDDI_VISTA
   2.298 +  NdisMSetAttributesEx(xi->adapter_handle, (NDIS_HANDLE)xi, 0, 0 /* the last zero is to give the next | something to | with */
   2.299 +    #ifdef NDIS51_MINIPORT
   2.300 +    |NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS
   2.301 +    #endif
   2.302 +    |NDIS_ATTRIBUTE_DESERIALIZE
   2.303 +    |NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK,
   2.304 +    NdisInterfaceInternal); /* PnpBus option doesn't exist... */
   2.305 +  #else
   2.306 +  registration_attributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
   2.307 +  registration_attributes.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
   2.308 +  registration_attributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
   2.309 +  registration_attributes.MiniportAdapterContext = xi;
   2.310 +  registration_attributes.AttributeFlags = 0;
   2.311 +  registration_attributes.AttributeFlags |= NDIS_MINIPORT_ATTRIBUTES_HARDWARE_DEVICE;
   2.312 +  registration_attributes.AttributeFlags |= NDIS_MINIPORT_ATTRIBUTES_SURPRISE_REMOVE_OK;
   2.313 +  registration_attributes.CheckForHangTimeInSeconds = 0; /* use default */
   2.314 +  registration_attributes.InterfaceType = NdisInterfacePNPBus;
   2.315 +  status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&registration_attributes);
   2.316 +  if (!NT_SUCCESS(status)) {
   2.317 +    FUNCTION_MSG("NdisMSetMiniportAttributes(registration) failed (%08x)\n", status);
   2.318 +    goto err;
   2.319 +  }
   2.320 +  
   2.321 +  general_attributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
   2.322 +  general_attributes.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1; /* revision 2 is NDIS 6.2 */
   2.323 +  general_attributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
   2.324 +  general_attributes.Flags = 0;
   2.325 +  general_attributes.MediaType = NdisMedium802_3;
   2.326 +  general_attributes.PhysicalMediumType = NdisPhysicalMediumOther;
   2.327 +  general_attributes.MtuSize = xi->current_mtu_value;
   2.328 +  general_attributes.MaxXmitLinkSpeed = MAX_LINK_SPEED;
   2.329 +  general_attributes.XmitLinkSpeed = MAX_LINK_SPEED;
   2.330 +  general_attributes.MaxRcvLinkSpeed = MAX_LINK_SPEED;
   2.331 +  general_attributes.RcvLinkSpeed = MAX_LINK_SPEED;
   2.332 +  general_attributes.MediaConnectState = MediaConnectStateConnected;
   2.333 +  general_attributes.MediaDuplexState = MediaDuplexStateFull;
   2.334 +  general_attributes.LookaheadSize = xi->current_lookahead;
   2.335 +  general_attributes.PowerManagementCapabilities = NULL;
   2.336 +  general_attributes.MacOptions = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | 
   2.337 +        NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
   2.338 +        NDIS_MAC_OPTION_NO_LOOPBACK;
   2.339 +  general_attributes.SupportedPacketFilters = SUPPORTED_PACKET_FILTERS;
   2.340 +  general_attributes.MaxMulticastListSize = MULTICAST_LIST_MAX_SIZE;
   2.341 +  general_attributes.MacAddressLength = 6;
   2.342 +  NdisMoveMemory(general_attributes.PermanentMacAddress, xi->perm_mac_addr, general_attributes.MacAddressLength);
   2.343 +  NdisMoveMemory(general_attributes.CurrentMacAddress, xi->curr_mac_addr, general_attributes.MacAddressLength);
   2.344 +  general_attributes.RecvScaleCapabilities = NULL; /* we do want to support this soon */
   2.345 +  general_attributes.AccessType = NET_IF_ACCESS_BROADCAST;
   2.346 +  general_attributes.DirectionType = NET_IF_DIRECTION_SENDRECEIVE;
   2.347 +  general_attributes.ConnectionType = NET_IF_CONNECTION_DEDICATED;
   2.348 +  general_attributes.IfType = IF_TYPE_ETHERNET_CSMACD;
   2.349 +  general_attributes.IfConnectorPresent = TRUE;
   2.350 +  general_attributes.SupportedStatistics = xi->stats.SupportedStatistics;
   2.351 +  general_attributes.SupportedPauseFunctions = NdisPauseFunctionsUnsupported;
   2.352 +  general_attributes.DataBackFillSize = 0; // see NdisRetreatNetBufferDataStart
   2.353 +  general_attributes.ContextBackFillSize = 0; // ?? NFI ??
   2.354 +  
   2.355 +  for (i = 0; xennet_oids[i].oid; i++);
   2.356 +  
   2.357 +  status = NdisAllocateMemoryWithTag((PVOID)&supported_oids, sizeof(NDIS_OID) * i, XENNET_POOL_TAG);
   2.358 +  if (!NT_SUCCESS(status)) {
   2.359 +    FUNCTION_MSG("NdisAllocateMemoryWithTag failed with 0x%x\n", status);
   2.360 +    status = NDIS_STATUS_RESOURCES;
   2.361 +    goto err;
   2.362 +  }
   2.363 +
   2.364 +  for (i = 0; xennet_oids[i].oid; i++) {
   2.365 +    supported_oids[i] = xennet_oids[i].oid;
   2.366 +    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);
   2.367 +  }
   2.368 +  general_attributes.SupportedOidList = supported_oids;
   2.369 +  general_attributes.SupportedOidListLength = sizeof(NDIS_OID) * i;
   2.370 +  general_attributes.AutoNegotiationFlags = NDIS_LINK_STATE_XMIT_LINK_SPEED_AUTO_NEGOTIATED
   2.371 +    | NDIS_LINK_STATE_RCV_LINK_SPEED_AUTO_NEGOTIATED
   2.372 +    | NDIS_LINK_STATE_DUPLEX_AUTO_NEGOTIATED;
   2.373 +  //general_attributes.PowerManagementCapabilitiesEx = NULL; // >= 6.20
   2.374 +  status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&general_attributes);
   2.375 +  if (!NT_SUCCESS(status)) {
   2.376 +    FUNCTION_MSG("NdisMSetMiniportAttributes(general) failed (%08x)\n", status);
   2.377 +    goto err;
   2.378 +  }
   2.379 +  NdisFreeMemory(supported_oids, 0, 0);
   2.380 +    
   2.381 +  /* this is the initial offload state */
   2.382 +  RtlZeroMemory(&df_offload, sizeof(df_offload));
   2.383 +  df_offload.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
   2.384 +  df_offload.Header.Revision = NDIS_OFFLOAD_REVISION_1; // revision 2 does exist
   2.385 +  df_offload.Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;
   2.386 +  /* this is the supported offload state */
   2.387 +  RtlZeroMemory(&hw_offload, sizeof(hw_offload));
   2.388 +  hw_offload.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
   2.389 +  hw_offload.Header.Revision = NDIS_OFFLOAD_REVISION_1; // revision 2 does exist
   2.390 +  hw_offload.Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;
   2.391 +  if (xi->current_csum_supported)
   2.392 +  {
   2.393 +    df_offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
   2.394 +    df_offload.Checksum.IPv4Transmit.IpOptionsSupported = NDIS_OFFLOAD_SET_ON;
   2.395 +    df_offload.Checksum.IPv4Transmit.TcpOptionsSupported = NDIS_OFFLOAD_SET_ON;
   2.396 +    df_offload.Checksum.IPv4Transmit.TcpChecksum = NDIS_OFFLOAD_SET_ON;
   2.397 +    df_offload.Checksum.IPv4Transmit.UdpChecksum = NDIS_OFFLOAD_SET_ON;
   2.398 +    df_offload.Checksum.IPv4Transmit.IpChecksum = NDIS_OFFLOAD_SET_ON;
   2.399 +    df_offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
   2.400 +    df_offload.Checksum.IPv4Receive.IpOptionsSupported = NDIS_OFFLOAD_SET_ON;
   2.401 +    df_offload.Checksum.IPv4Receive.TcpOptionsSupported = NDIS_OFFLOAD_SET_ON;
   2.402 +    df_offload.Checksum.IPv4Receive.TcpChecksum = NDIS_OFFLOAD_SET_ON;
   2.403 +    df_offload.Checksum.IPv4Receive.UdpChecksum = NDIS_OFFLOAD_SET_ON;
   2.404 +    df_offload.Checksum.IPv4Receive.IpChecksum = NDIS_OFFLOAD_SET_ON;
   2.405 +    /* offload.Checksum.IPv6Transmit is not supported */
   2.406 +    /* offload.Checksum.IPv6Receive is not supported */
   2.407 +    hw_offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
   2.408 +    hw_offload.Checksum.IPv4Transmit.IpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;
   2.409 +    hw_offload.Checksum.IPv4Transmit.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;
   2.410 +    hw_offload.Checksum.IPv4Transmit.TcpChecksum = NDIS_OFFLOAD_SUPPORTED;
   2.411 +    hw_offload.Checksum.IPv4Transmit.UdpChecksum = NDIS_OFFLOAD_SUPPORTED;
   2.412 +    hw_offload.Checksum.IPv4Transmit.IpChecksum = NDIS_OFFLOAD_SUPPORTED;
   2.413 +    hw_offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
   2.414 +    hw_offload.Checksum.IPv4Receive.IpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;
   2.415 +    hw_offload.Checksum.IPv4Receive.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;
   2.416 +    hw_offload.Checksum.IPv4Receive.TcpChecksum = NDIS_OFFLOAD_SUPPORTED;
   2.417 +    hw_offload.Checksum.IPv4Receive.UdpChecksum = NDIS_OFFLOAD_SUPPORTED;
   2.418 +    hw_offload.Checksum.IPv4Receive.IpChecksum = NDIS_OFFLOAD_SUPPORTED;
   2.419 +    /* hw_offload.Checksum.IPv6Transmit is not supported */
   2.420 +    /* hw_offload.Checksum.IPv6Receive is not supported */
   2.421 +  }
   2.422 +  if (xi->current_gso_value)
   2.423 +  {
   2.424 +    hw_offload.LsoV1.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
   2.425 +    hw_offload.LsoV1.IPv4.MaxOffLoadSize = xi->current_gso_value;
   2.426 +    hw_offload.LsoV1.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
   2.427 +    hw_offload.LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */
   2.428 +    hw_offload.LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */
   2.429 +    hw_offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
   2.430 +    hw_offload.LsoV2.IPv4.MaxOffLoadSize = xi->current_gso_value;
   2.431 +    hw_offload.LsoV2.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
   2.432 +    /* hw_offload.LsoV2.IPv6 is not supported */
   2.433 +    df_offload.LsoV1.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
   2.434 +    df_offload.LsoV1.IPv4.MaxOffLoadSize = xi->current_gso_value;
   2.435 +    df_offload.LsoV1.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
   2.436 +    df_offload.LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */
   2.437 +    df_offload.LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */
   2.438 +    df_offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
   2.439 +    df_offload.LsoV2.IPv4.MaxOffLoadSize = xi->current_gso_value;
   2.440 +    df_offload.LsoV2.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
   2.441 +    /* df_offload.LsoV2.IPv6 is not supported */
   2.442 +  }
   2.443 +  /* hw_offload.IPsecV1 is not supported */
   2.444 +  /* hw_offload.IPsecV2 is not supported */
   2.445 +  /* df_offload.IPsecV1 is not supported */
   2.446 +  /* df_offload.IPsecV2 is not supported */
   2.447 +  hw_offload.Flags = 0;
   2.448 +  df_offload.Flags = 0;
   2.449 +  
   2.450 +  RtlZeroMemory(&df_conn_offload, sizeof(df_conn_offload));
   2.451 +  df_conn_offload.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
   2.452 +  df_conn_offload.Header.Revision = NDIS_TCP_CONNECTION_OFFLOAD_REVISION_1;
   2.453 +  df_conn_offload.Header.Size = NDIS_SIZEOF_TCP_CONNECTION_OFFLOAD_REVISION_1;
   2.454 +
   2.455 +  RtlZeroMemory(&hw_conn_offload, sizeof(hw_conn_offload));
   2.456 +  hw_conn_offload.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
   2.457 +  hw_conn_offload.Header.Revision = NDIS_TCP_CONNECTION_OFFLOAD_REVISION_1;
   2.458 +  hw_conn_offload.Header.Size = NDIS_SIZEOF_TCP_CONNECTION_OFFLOAD_REVISION_1;
   2.459 +  
   2.460 +  offload_attributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES;
   2.461 +  offload_attributes.Header.Revision = NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
   2.462 +  offload_attributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
   2.463 +  offload_attributes.DefaultOffloadConfiguration = &df_offload;
   2.464 +  offload_attributes.HardwareOffloadCapabilities = &hw_offload;
   2.465 +  offload_attributes.DefaultTcpConnectionOffloadConfiguration = &df_conn_offload;
   2.466 +  offload_attributes.TcpConnectionOffloadHardwareCapabilities  = &hw_conn_offload;
   2.467 +  status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&offload_attributes);
   2.468 +  if (!NT_SUCCESS(status)) {
   2.469 +    FUNCTION_MSG("NdisMSetMiniportAttributes(offload) failed (%08x)\n", status);
   2.470 +    goto err;
   2.471 +  }
   2.472 +  
   2.473 +  #if 0
   2.474 +  if (ndis_os_minor_version >= 1) {
   2.475 +    NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES hw_assist_attributes;
   2.476 +    NDIS_HD_SPLIT_ATTRIBUTES hd_split_attributes;
   2.477 +    
   2.478 +    RtlZeroMemory(&hd_split_attributes, sizeof(hd_split_attributes));
   2.479 +    hd_split_attributes.Header.Type = NDIS_OBJECT_TYPE_HD_SPLIT_ATTRIBUTES;
   2.480 +    hd_split_attributes.Header.Revision = NDIS_HD_SPLIT_ATTRIBUTES_REVISION_1;
   2.481 +    hd_split_attributes.Header.Size = NDIS_SIZEOF_HD_SPLIT_ATTRIBUTES_REVISION_1;
   2.482 +    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;
   2.483 +    hd_split_attributes.CurrentCapabilities = hd_split_attributes.HardwareCapabilities;
   2.484 +    /* the other members are set on output */
   2.485 +    
   2.486 +    RtlZeroMemory(&hw_assist_attributes, sizeof(hw_assist_attributes));
   2.487 +    hw_assist_attributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES;
   2.488 +    hw_assist_attributes.Header.Revision = NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;
   2.489 +    hw_assist_attributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;
   2.490 +    hw_assist_attributes.HDSplitAttributes = &hd_split_attributes;
   2.491 +    status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&hw_assist_attributes);
   2.492 +    if (!NT_SUCCESS(status))
   2.493 +    {
   2.494 +      FUNCTION_MSG("NdisMSetMiniportAttributes(hw_assist) failed (%08x)\n", status);
   2.495 +      goto err;
   2.496 +    }
   2.497 +    FUNCTION_MSG("HW Split enabled\n");
   2.498 +    FUNCTION_MSG(" HDSplitFlags = %08x\n", hd_split_attributes.HDSplitFlags);
   2.499 +    FUNCTION_MSG(" BackfillSize = %d\n", hd_split_attributes.BackfillSize);
   2.500 +    FUNCTION_MSG(" MaxHeaderSize = %d\n", hd_split_attributes.MaxHeaderSize);
   2.501 +    //what about backfill here?
   2.502 +  }
   2.503 +  #endif
   2.504 +  #endif
   2.505 +  if (xi->device_state != DEVICE_STATE_INACTIVE)
   2.506 +    xi->device_state = DEVICE_STATE_ACTIVE;
   2.507 +  FUNCTION_EXIT();
   2.508 +  return NDIS_STATUS_SUCCESS;
   2.509 +  
   2.510 +err:
   2.511 +  if (xi) {
   2.512 +    NdisFreeMemory(xi, 0, 0);
   2.513 +  }
   2.514 +  FUNCTION_EXIT_STATUS(status);
   2.515 +
   2.516 +  return status;
   2.517 +}
   2.518 +
   2.519 +#if NTDDI_VERSION < NTDDI_VISTA
   2.520 +static VOID
   2.521 +XenNet_PnPEventNotify(NDIS_HANDLE adapter_context, NDIS_DEVICE_PNP_EVENT pnp_event, PVOID information_buffer, ULONG information_buffer_length) {
   2.522 +  UNREFERENCED_PARAMETER(information_buffer);
   2.523 +  UNREFERENCED_PARAMETER(information_buffer_length);
   2.524 +  UNREFERENCED_PARAMETER(adapter_context);
   2.525 +
   2.526 +  FUNCTION_ENTER();
   2.527 +  switch (pnp_event)
   2.528 +  {
   2.529 +  case NdisDevicePnPEventSurpriseRemoved:
   2.530 +    FUNCTION_MSG("NdisDevicePnPEventSurpriseRemoved\n");
   2.531 +    break;
   2.532 +  case NdisDevicePnPEventPowerProfileChanged :
   2.533 +    FUNCTION_MSG("NdisDevicePnPEventPowerProfileChanged\n");
   2.534 +    break;
   2.535 +  default:
   2.536 +    FUNCTION_MSG("NdisDevicePnPEvent%d\n", pnp_event);
   2.537 +    break;
   2.538 +  }
   2.539 +  FUNCTION_EXIT();
   2.540 +}
   2.541 +#else
   2.542 +static VOID
   2.543 +XenNet_DevicePnPEventNotify(NDIS_HANDLE adapter_context, PNET_DEVICE_PNP_EVENT pnp_event) {
   2.544 +  UNREFERENCED_PARAMETER(adapter_context);
   2.545 +
   2.546 +  FUNCTION_ENTER();
   2.547 +  switch (pnp_event->DevicePnPEvent)
   2.548 +  {
   2.549 +  case NdisDevicePnPEventSurpriseRemoved:
   2.550 +    FUNCTION_MSG("NdisDevicePnPEventSurpriseRemoved\n");
   2.551 +    break;
   2.552 +  case NdisDevicePnPEventPowerProfileChanged :
   2.553 +    FUNCTION_MSG("NdisDevicePnPEventPowerProfileChanged\n");
   2.554 +    break;
   2.555 +  default:
   2.556 +    FUNCTION_MSG("NdisDevicePnPEvent%d\n", pnp_event->DevicePnPEvent);
   2.557 +    break;
   2.558 +  }
   2.559 +  FUNCTION_EXIT();
   2.560 +}
   2.561 +#endif
   2.562 +
   2.563 +/* called at <= HIGH_IRQL, or PASSIVE_LEVEL, depending on shutdown_action */
   2.564 +static VOID
   2.565 +#if NTDDI_VERSION < NTDDI_VISTA
   2.566 +XenNet_Shutdown(NDIS_HANDLE adapter_context) {
   2.567 +#else
   2.568 +XenNet_Shutdown(NDIS_HANDLE adapter_context, NDIS_SHUTDOWN_ACTION shutdown_action) {
   2.569 +  UNREFERENCED_PARAMETER(shutdown_action);
   2.570 +#endif
   2.571 +  UNREFERENCED_PARAMETER(adapter_context);
   2.572 +  FUNCTION_ENTER();
   2.573 +  FUNCTION_EXIT();
   2.574 +}
   2.575 +
   2.576 +static BOOLEAN
   2.577 +XenNet_CheckForHang(NDIS_HANDLE adapter_context)
   2.578 +{
   2.579 +  UNREFERENCED_PARAMETER(adapter_context);
   2.580 +
   2.581 +  //FUNCTION_ENTER();
   2.582 +  //FUNCTION_EXIT();
   2.583 +  return FALSE;
   2.584 +}
   2.585 +
   2.586 +/* Opposite of XenNet_Init */
   2.587 +static VOID
   2.588 +#if NTDDI_VERSION < NTDDI_VISTA
   2.589 +XenNet_Halt(NDIS_HANDLE adapter_context) {
   2.590 +#else
   2.591 +XenNet_Halt(NDIS_HANDLE adapter_context, NDIS_HALT_ACTION halt_action) {
   2.592 +#endif
   2.593 +  struct xennet_info *xi = adapter_context;
   2.594 +#if NTDDI_VERSION < NTDDI_VISTA
   2.595 +#else
   2.596 +  UNREFERENCED_PARAMETER(halt_action);
   2.597 +#endif
   2.598 +  FUNCTION_ENTER();
   2.599 +  XenNet_Disconnect(xi, FALSE);
   2.600 +  NdisFreeMemory(xi, 0, 0);
   2.601 +
   2.602 +  FUNCTION_EXIT();
   2.603 +}
   2.604 +
   2.605 +static NDIS_STATUS 
   2.606 +XenNet_Reset(NDIS_HANDLE adapter_context, PBOOLEAN addressing_reset)
   2.607 +{
   2.608 +  UNREFERENCED_PARAMETER(adapter_context);
   2.609 +
   2.610 +  FUNCTION_ENTER();
   2.611 +  *addressing_reset = FALSE;
   2.612 +  FUNCTION_EXIT();
   2.613 +  return NDIS_STATUS_SUCCESS;
   2.614 +}
   2.615 +
   2.616 +#if NTDDI_VERSION < NTDDI_VISTA
   2.617 +#else
   2.618 +/* called at PASSIVE_LEVEL */
   2.619 +static NDIS_STATUS
   2.620 +XenNet_Pause(NDIS_HANDLE adapter_context, PNDIS_MINIPORT_PAUSE_PARAMETERS pause_parameters)
   2.621 +{
   2.622 +  UNREFERENCED_PARAMETER(adapter_context);
   2.623 +  UNREFERENCED_PARAMETER(pause_parameters);
   2.624 +  FUNCTION_ENTER();
   2.625 +  FUNCTION_EXIT();
   2.626 +  return STATUS_SUCCESS;
   2.627 +}
   2.628 +
   2.629 +/* called at PASSIVE_LEVEL */
   2.630 +static NDIS_STATUS
   2.631 +XenNet_Restart(NDIS_HANDLE adapter_context, PNDIS_MINIPORT_RESTART_PARAMETERS restart_parameters)
   2.632 +{
   2.633 +  UNREFERENCED_PARAMETER(adapter_context);
   2.634 +  UNREFERENCED_PARAMETER(restart_parameters);
   2.635 +  FUNCTION_ENTER();
   2.636 +  FUNCTION_EXIT();
   2.637 +  return STATUS_SUCCESS;
   2.638 +}
   2.639 +
   2.640 +static VOID
   2.641 +XenNet_Unload(PDRIVER_OBJECT driver_object)
   2.642 +{
   2.643 +  UNREFERENCED_PARAMETER(driver_object);
   2.644 +  FUNCTION_ENTER();
   2.645 +  NdisMDeregisterMiniportDriver(driver_handle);
   2.646 +  FUNCTION_EXIT();
   2.647 +}
   2.648 +
   2.649 +static NDIS_STATUS
   2.650 +XenNet_SetOptions(NDIS_HANDLE driver_handle, NDIS_HANDLE driver_context)
   2.651 +{
   2.652 +  UNREFERENCED_PARAMETER(driver_handle);
   2.653 +  UNREFERENCED_PARAMETER(driver_context);
   2.654 +  FUNCTION_ENTER();
   2.655 +  FUNCTION_EXIT();
   2.656 +  return STATUS_SUCCESS;
   2.657 +}
   2.658 +#endif
   2.659 +
   2.660 +NTSTATUS
   2.661 +DriverEntry(PDRIVER_OBJECT driver_object, PUNICODE_STRING registry_path)
   2.662 +{
   2.663 +  NTSTATUS status;
   2.664 +  ULONG ndis_version;
   2.665 +  #if NTDDI_VERSION < NTDDI_VISTA
   2.666 +  NDIS_HANDLE ndis_wrapper_handle = NULL;
   2.667 +  NDIS_MINIPORT_CHARACTERISTICS mini_chars;
   2.668 +  #else
   2.669 +  NDIS_MINIPORT_DRIVER_CHARACTERISTICS mini_chars;
   2.670 +  #endif
   2.671 +  
   2.672 +  FUNCTION_ENTER();
   2.673 +
   2.674 +  NdisZeroMemory(&mini_chars, sizeof(mini_chars));
   2.675 +
   2.676 +  ndis_version = NdisGetVersion();
   2.677 +  
   2.678 +  ndis_os_major_version = ndis_version >> 16;
   2.679 +  ndis_os_minor_version = ndis_version & 0xFFFF;
   2.680 +
   2.681 +  FUNCTION_MSG("Driver MajorNdisVersion = %d, Driver MinorNdisVersion = %d\n", NDIS_MINIPORT_MAJOR_VERSION, NDIS_MINIPORT_MINOR_VERSION);
   2.682 +  FUNCTION_MSG("Windows MajorNdisVersion = %d, Windows MinorNdisVersion = %d\n", ndis_os_major_version, ndis_os_minor_version);
   2.683 +
   2.684 +  #if NTDDI_VERSION < NTDDI_VISTA
   2.685 +  NdisMInitializeWrapper(&ndis_wrapper_handle, driver_object, registry_path, NULL);
   2.686 +  if (!ndis_wrapper_handle) {
   2.687 +    FUNCTION_MSG("NdisMInitializeWrapper failed\n");
   2.688 +    return NDIS_STATUS_FAILURE;
   2.689 +  }
   2.690 +
   2.691 +  mini_chars.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION;
   2.692 +  mini_chars.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION;
   2.693 +  mini_chars.HaltHandler = XenNet_Halt;
   2.694 +  mini_chars.InitializeHandler = XenNet_Init;
   2.695 +  mini_chars.QueryInformationHandler = XenNet_QueryInformation;
   2.696 +  mini_chars.ResetHandler = XenNet_Reset;
   2.697 +  mini_chars.SetInformationHandler = XenNet_SetInformation;
   2.698 +  mini_chars.ReturnPacketHandler = XenNet_ReturnPacket;
   2.699 +  mini_chars.SendPacketsHandler = XenNet_SendPackets;
   2.700 +  #ifdef NDIS51_MINIPORT
   2.701 +  mini_chars.PnPEventNotifyHandler = XenNet_PnPEventNotify;
   2.702 +  mini_chars.AdapterShutdownHandler = XenNet_Shutdown;
   2.703 +  #endif
   2.704 +  status = NdisMRegisterMiniport(ndis_wrapper_handle, &mini_chars, sizeof(mini_chars));
   2.705 +  if (!NT_SUCCESS(status)) {
   2.706 +    FUNCTION_MSG("NdisMRegisterMiniport failed, status = 0x%x\n", status);
   2.707 +    NdisTerminateWrapper(ndis_wrapper_handle, NULL);
   2.708 +    return status;
   2.709 +  }
   2.710 +  #else
   2.711 +  mini_chars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS;
   2.712 +  
   2.713 +  if (ndis_os_minor_version < 1) {
   2.714 +    mini_chars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
   2.715 +    mini_chars.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
   2.716 +
   2.717 +    mini_chars.MajorNdisVersion = 6;
   2.718 +    mini_chars.MinorNdisVersion = 0;
   2.719 +  } else {
   2.720 +    mini_chars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
   2.721 +    mini_chars.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
   2.722 +    mini_chars.MajorNdisVersion = 6;
   2.723 +    mini_chars.MinorNdisVersion = 1;
   2.724 +  }
   2.725 +  mini_chars.MajorDriverVersion = VENDOR_DRIVER_VERSION_MAJOR;
   2.726 +  mini_chars.MinorDriverVersion = VENDOR_DRIVER_VERSION_MINOR;
   2.727 +
   2.728 +  mini_chars.Flags = NDIS_WDM_DRIVER;
   2.729 +  
   2.730 +  mini_chars.SetOptionsHandler = XenNet_SetOptions;
   2.731 +  mini_chars.InitializeHandlerEx = XenNet_Initialize;
   2.732 +  mini_chars.HaltHandlerEx = XenNet_Halt;
   2.733 +  mini_chars.UnloadHandler = XenNet_Unload;
   2.734 +  mini_chars.PauseHandler = XenNet_Pause;
   2.735 +  mini_chars.RestartHandler = XenNet_Restart;
   2.736 +  mini_chars.CheckForHangHandlerEx = XenNet_CheckForHang;
   2.737 +  mini_chars.ResetHandlerEx = XenNet_Reset;
   2.738 +  mini_chars.DevicePnPEventNotifyHandler = XenNet_DevicePnPEventNotify;
   2.739 +  mini_chars.ShutdownHandlerEx = XenNet_Shutdown;
   2.740 +
   2.741 +  mini_chars.OidRequestHandler = XenNet_OidRequest;
   2.742 +  mini_chars.CancelOidRequestHandler = XenNet_CancelOidRequest;
   2.743 +  if (ndis_os_minor_version >= 1) {
   2.744 +    mini_chars.DirectOidRequestHandler = NULL;
   2.745 +    mini_chars.CancelDirectOidRequestHandler = NULL;
   2.746 +  }
   2.747 +
   2.748 +  mini_chars.SendNetBufferListsHandler = XenNet_SendNetBufferLists;
   2.749 +  //mini_chars.CancelSendHandler = XenNet_CancelSend;
   2.750 +
   2.751 +  mini_chars.ReturnNetBufferListsHandler = XenNet_ReturnNetBufferLists;
   2.752 +
   2.753 +  status = NdisMRegisterMiniportDriver(driver_object, registry_path, NULL, &mini_chars, &driver_handle);
   2.754 +  if (!NT_SUCCESS(status)) {
   2.755 +    FUNCTION_MSG("NdisMRegisterMiniportDriver failed, status = 0x%x\n", status);
   2.756 +    return status;
   2.757 +  }
   2.758 +  #endif
   2.759 +  FUNCTION_EXIT();
   2.760 +
   2.761 +  return status;
   2.762 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xennet/xennet.h	Sun Feb 10 23:14:05 2013 +1100
     3.3 @@ -0,0 +1,495 @@
     3.4 +/*
     3.5 +PV Drivers for Windows Xen HVM Domains
     3.6 +Copyright (C) 2007 James Harper
     3.7 +Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
     3.8 +
     3.9 +This program is free software; you can redistribute it and/or
    3.10 +modify it under the terms of the GNU General Public License
    3.11 +as published by the Free Software Foundation; either version 2
    3.12 +of the License, or (at your option) any later version.
    3.13 +
    3.14 +This program is distributed in the hope that it will be useful,
    3.15 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.16 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.17 +GNU General Public License for more details.
    3.18 +
    3.19 +You should have received a copy of the GNU General Public License
    3.20 +along with this program; if not, write to the Free Software
    3.21 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    3.22 +*/
    3.23 +
    3.24 +#pragma warning(disable: 4201)
    3.25 +#pragma warning(disable: 4214)
    3.26 +
    3.27 +#include <ntddk.h>
    3.28 +#include <wdm.h>
    3.29 +#define NDIS_MINIPORT_DRIVER 1
    3.30 +#if NTDDI_VERSION < NTDDI_WINXP
    3.31 +# define NDIS50_MINIPORT 1
    3.32 +#elif NTDDI_VERSION < NTDDI_VISTA
    3.33 +# define NDIS51_MINIPORT 1
    3.34 +#else
    3.35 +# define NDIS61_MINIPORT 1
    3.36 +#endif
    3.37 +#include <ndis.h>
    3.38 +#define NTSTRSAFE_LIB
    3.39 +#include <ntstrsafe.h>
    3.40 +#include <liblfds.h>
    3.41 +
    3.42 +#define VENDOR_DRIVER_VERSION_MAJOR 0
    3.43 +#define VENDOR_DRIVER_VERSION_MINOR 11
    3.44 +
    3.45 +#define MAX_LINK_SPEED 10000000000L /* there is not really any theoretical maximum... */
    3.46 +
    3.47 +#define VENDOR_DRIVER_VERSION (((VENDOR_DRIVER_VERSION_MAJOR) << 16) | (VENDOR_DRIVER_VERSION_MINOR))
    3.48 +
    3.49 +#define __DRIVER_NAME "XenNet"
    3.50 +
    3.51 +#define PACKET_NEXT_PACKET_FIELD MiniportReservedEx[sizeof(PVOID)] // RX & TX
    3.52 +#define PACKET_FIRST_PB_FIELD MiniportReservedEx[0] // RX
    3.53 +#define PACKET_LIST_ENTRY_FIELD MiniportReservedEx[sizeof(PVOID)] // TX (2 entries)
    3.54 +#define PACKET_NEXT_PACKET(_packet) (*(PNDIS_PACKET *)&(_packet)->PACKET_NEXT_PACKET_FIELD)
    3.55 +#define PACKET_LIST_ENTRY(_packet) (*(PLIST_ENTRY)&(_packet)->PACKET_LIST_ENTRY_FIELD)
    3.56 +#define PACKET_FIRST_PB(_packet) (*(shared_buffer_t **)&(_packet)->PACKET_FIRST_PB_FIELD)
    3.57 +
    3.58 +#define NB_LIST_ENTRY_FIELD MiniportReserved[0] // TX (2 entries)
    3.59 +#define NB_FIRST_PB_FIELD MiniportReserved[0] // RX
    3.60 +#define NB_NBL_FIELD MiniportReserved[2] // TX
    3.61 +#define NB_LIST_ENTRY(_nb) (*(PLIST_ENTRY)&(_nb)->NB_LIST_ENTRY_FIELD)
    3.62 +#define NB_NBL(_nb) (*(PNET_BUFFER_LIST *)&(_nb)->NB_NBL_FIELD)
    3.63 +#define NB_FIRST_PB(_nb) (*(shared_buffer_t **)&(_nb)->NB_FIRST_PB_FIELD)
    3.64 +
    3.65 +#define NBL_REF_FIELD MiniportReserved[0] // TX
    3.66 +#define NBL_REF(_nbl) (*(ULONG_PTR *)&(_nbl)->NBL_REF_FIELD)
    3.67 +
    3.68 +#define NDIS_STATUS_RESOURCES_MAX_LENGTH 64
    3.69 +
    3.70 +#include <xen_windows.h>
    3.71 +#include <memory.h>
    3.72 +#include <grant_table.h>
    3.73 +#include <event_channel.h>
    3.74 +#include <hvm/params.h>
    3.75 +#include <hvm/hvm_op.h>
    3.76 +#include <xen_public.h>
    3.77 +#include <io/ring.h>
    3.78 +#include <io/netif.h>
    3.79 +#include <io/xenbus.h>
    3.80 +#include <stdlib.h>
    3.81 +#define XENNET_POOL_TAG (ULONG) 'XenN'
    3.82 +
    3.83 +/* Xen macros use these, so they need to be redefined to Win equivs */
    3.84 +#define wmb() KeMemoryBarrier()
    3.85 +#define mb() KeMemoryBarrier()
    3.86 +
    3.87 +#define GRANT_INVALID_REF 0
    3.88 +
    3.89 +#define NAME_SIZE 64
    3.90 +
    3.91 +#define ETH_ALEN 6
    3.92 +
    3.93 +static FORCEINLINE USHORT
    3.94 +GET_NET_USHORT(USHORT data) {
    3.95 +  return (data << 8) | (data >> 8);
    3.96 +}
    3.97 +
    3.98 +static FORCEINLINE USHORT
    3.99 +GET_NET_PUSHORT(PVOID pdata) {
   3.100 +  return (*((PUSHORT)pdata) << 8) | (*((PUSHORT)pdata) >> 8);
   3.101 +}
   3.102 +
   3.103 +static FORCEINLINE VOID
   3.104 +SET_NET_USHORT(PVOID ptr, USHORT data) {
   3.105 +  *((PUSHORT)ptr) = GET_NET_USHORT(data);
   3.106 +}
   3.107 +
   3.108 +static FORCEINLINE ULONG
   3.109 +GET_NET_ULONG(ULONG data) {
   3.110 +  ULONG tmp;
   3.111 +  
   3.112 +  tmp = ((data & 0x00ff00ff) << 8) | ((data & 0xff00ff00) >> 8);
   3.113 +  return (tmp << 16) | (tmp >> 16);
   3.114 +}
   3.115 +
   3.116 +static FORCEINLINE ULONG
   3.117 +GET_NET_PULONG(PVOID pdata) {
   3.118 +  ULONG tmp;
   3.119 +  
   3.120 +  tmp = ((*((PULONG)pdata) & 0x00ff00ff) << 8) | ((*((PULONG)pdata) & 0xff00ff00) >> 8);
   3.121 +  return (tmp << 16) | (tmp >> 16);
   3.122 +}
   3.123 +
   3.124 +static FORCEINLINE VOID
   3.125 +SET_NET_ULONG(PVOID ptr, ULONG data) {
   3.126 +  *((PULONG)ptr) = GET_NET_ULONG(data);
   3.127 +}
   3.128 +/*
   3.129 +#define GET_NET_ULONG(x) ((GET_NET_USHORT(x) << 16) | GET_NET_USHORT(((PUCHAR)&x)[2]))
   3.130 +#define SET_NET_ULONG(y, x) *((ULONG *)&(y)) = ((GET_NET_USHORT(x) << 16) | GET_NET_USHORT(((PUCHAR)&x)[2]))
   3.131 +*/
   3.132 +
   3.133 +#define SUPPORTED_PACKET_FILTERS (\
   3.134 +  NDIS_PACKET_TYPE_DIRECTED | \
   3.135 +  NDIS_PACKET_TYPE_MULTICAST | \
   3.136 +  NDIS_PACKET_TYPE_BROADCAST | \
   3.137 +  NDIS_PACKET_TYPE_PROMISCUOUS | \
   3.138 +  NDIS_PACKET_TYPE_ALL_MULTICAST)
   3.139 +
   3.140 +/* couldn't get regular xen ring macros to work...*/
   3.141 +#define __NET_RING_SIZE(type, _sz) \
   3.142 +    (__RD32( \
   3.143 +    (_sz - sizeof(struct type##_sring) + sizeof(union type##_sring_entry)) \
   3.144 +    / sizeof(union type##_sring_entry)))
   3.145 +
   3.146 +#define NET_TX_RING_SIZE __NET_RING_SIZE(netif_tx, PAGE_SIZE)
   3.147 +#define NET_RX_RING_SIZE __NET_RING_SIZE(netif_rx, PAGE_SIZE)
   3.148 +
   3.149 +#pragma warning(disable: 4127) // conditional expression is constant
   3.150 +
   3.151 +#define MIN_LARGE_SEND_SEGMENTS 4
   3.152 +
   3.153 +/* TODO: crank this up if we support higher mtus? */
   3.154 +#define XN_HDR_SIZE 14
   3.155 +#define XN_MAX_DATA_SIZE 1500
   3.156 +#define XN_MIN_FRAME_SIZE 60
   3.157 +#define XN_MAX_FRAME_SIZE (XN_HDR_SIZE + XN_DATA_SIZE)
   3.158 +/*
   3.159 +#if !defined(OFFLOAD_LARGE_SEND)
   3.160 +  #define XN_MAX_PKT_SIZE (XN_HDR_SIZE + XN_DATA_SIZE)
   3.161 +#else
   3.162 +  #define XN_MAX_PKT_SIZE MAX_LARGE_SEND_OFFLOAD
   3.163 +#endif
   3.164 +*/
   3.165 +
   3.166 +#define XN_MAX_SEND_PKTS 16
   3.167 +
   3.168 +#define XENSOURCE_MAC_HDR 0x00163E
   3.169 +#define XN_VENDOR_DESC "Xensource"
   3.170 +#define MAX_XENBUS_STR_LEN 128
   3.171 +
   3.172 +#define RX_MIN_TARGET 8
   3.173 +#define RX_DFL_MIN_TARGET 256
   3.174 +#define RX_MAX_TARGET min(NET_RX_RING_SIZE, 256)
   3.175 +#define RX_MAX_PB_FREELIST (RX_MAX_TARGET * 4)
   3.176 +
   3.177 +//#define MAX_BUFFERS_PER_PACKET NET_RX_RING_SIZE
   3.178 +
   3.179 +#define MIN_ETH_HEADER_LENGTH 14
   3.180 +#define MAX_ETH_HEADER_LENGTH 14
   3.181 +#define MIN_IP4_HEADER_LENGTH 20
   3.182 +#define MAX_IP4_HEADER_LENGTH (15 * 4)
   3.183 +#define MIN_TCP_HEADER_LENGTH 20
   3.184 +#define MAX_TCP_HEADER_LENGTH (15 * 4)
   3.185 +#define MAX_PKT_HEADER_LENGTH (MAX_ETH_HEADER_LENGTH + MAX_IP4_HEADER_LENGTH + MAX_TCP_HEADER_LENGTH)
   3.186 +
   3.187 +#define MIN_LOOKAHEAD_LENGTH (MAX_IP4_HEADER_LENGTH + MAX_TCP_HEADER_LENGTH)
   3.188 +#define MAX_LOOKAHEAD_LENGTH PAGE_SIZE
   3.189 +
   3.190 +#define LINUX_MAX_SG_ELEMENTS 19
   3.191 +
   3.192 +#define PAGE_LIST_SIZE (max(NET_RX_RING_SIZE, NET_TX_RING_SIZE) * 4)
   3.193 +#define MULTICAST_LIST_MAX_SIZE 32
   3.194 +
   3.195 +#define TX_HEADER_BUFFER_SIZE 512
   3.196 +#define TX_COALESCE_BUFFERS (NET_TX_RING_SIZE)
   3.197 +
   3.198 +/* split incoming large packets into MSS sized chunks */
   3.199 +#define RX_LSO_SPLIT_MSS 0
   3.200 +/* split incoming large packets in half, to not invoke the delayed ack timer */
   3.201 +#define RX_LSO_SPLIT_HALF 1
   3.202 +/* don't split incoming large packets. not really useful */
   3.203 +#define RX_LSO_SPLIT_NONE 2
   3.204 +
   3.205 +#define DEVICE_STATE_DISCONNECTED  0 /* -> INITIALISING */
   3.206 +#define DEVICE_STATE_INITIALISING  1 /* -> ACTIVE or INACTIVE */
   3.207 +#define DEVICE_STATE_INACTIVE      2
   3.208 +#define DEVICE_STATE_ACTIVE        3 /* -> DISCONNECTING */
   3.209 +#define DEVICE_STATE_DISCONNECTING 4 /* -> DISCONNECTED */
   3.210 +
   3.211 +struct _shared_buffer_t;
   3.212 +
   3.213 +typedef struct _shared_buffer_t shared_buffer_t;
   3.214 +
   3.215 +struct _shared_buffer_t {
   3.216 +  struct netif_rx_response rsp;
   3.217 +  shared_buffer_t *next;
   3.218 +  grant_ref_t gref;
   3.219 +  //USHORT offset;
   3.220 +  PVOID virtual;
   3.221 +  PMDL mdl;
   3.222 +  //USHORT id;
   3.223 +  volatile LONG ref_count;
   3.224 +};
   3.225 +
   3.226 +typedef struct {
   3.227 +  //PNET_BUFFER packet; /* only set on the last packet */
   3.228 +  PNDIS_PACKET packet;
   3.229 +  PVOID *cb;
   3.230 +  grant_ref_t gref;
   3.231 +} tx_shadow_t;
   3.232 +
   3.233 +typedef struct {
   3.234 +  ULONG parse_result;
   3.235 +  PMDL first_mdl;
   3.236 +  MDL first_mdl_storage;
   3.237 +  PPFN_NUMBER first_mdl_pfns[17]; /* maximum possible packet size */
   3.238 +  PMDL curr_mdl;
   3.239 +  shared_buffer_t *first_pb;
   3.240 +  shared_buffer_t *curr_pb;
   3.241 +  PUCHAR first_mdl_virtual;
   3.242 +  //ULONG mdl_count;
   3.243 +  ULONG first_mdl_offset;
   3.244 +  ULONG first_mdl_length;
   3.245 +  ULONG curr_mdl_offset;
   3.246 +  USHORT mss;
   3.247 +  //NDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
   3.248 +  BOOLEAN csum_blank;
   3.249 +  BOOLEAN data_validated;
   3.250 +  BOOLEAN split_required;
   3.251 +  UCHAR ip_version;
   3.252 +  PUCHAR header;
   3.253 +  ULONG header_length;
   3.254 +  UCHAR ip_proto;
   3.255 +  BOOLEAN ip_has_options;
   3.256 +  ULONG total_length;
   3.257 +  USHORT ip4_header_length;
   3.258 +  USHORT ip4_length;
   3.259 +  USHORT tcp_header_length;
   3.260 +  BOOLEAN tcp_has_options;
   3.261 +  USHORT tcp_length;
   3.262 +  USHORT tcp_remaining;
   3.263 +  ULONG tcp_seq;
   3.264 +  BOOLEAN is_multicast;
   3.265 +  BOOLEAN is_broadcast;
   3.266 +  /* anything past here doesn't get cleared automatically by the ClearPacketInfo */
   3.267 +  UCHAR header_data[MAX_LOOKAHEAD_LENGTH + MAX_ETH_HEADER_LENGTH];
   3.268 +} packet_info_t;
   3.269 +
   3.270 +struct xennet_info
   3.271 +{
   3.272 +  ULONG device_state;
   3.273 +  
   3.274 +  /* Base device vars */
   3.275 +  PDEVICE_OBJECT pdo;
   3.276 +  PDEVICE_OBJECT fdo;
   3.277 +  PDEVICE_OBJECT lower_do;
   3.278 +//  WCHAR dev_desc[NAME_SIZE];
   3.279 +
   3.280 +  /* NDIS-related vars */
   3.281 +  NDIS_HANDLE adapter_handle;
   3.282 +  ULONG packet_filter;
   3.283 +  uint8_t perm_mac_addr[ETH_ALEN];
   3.284 +  uint8_t curr_mac_addr[ETH_ALEN];
   3.285 +  ULONG current_lookahead;
   3.286 +
   3.287 +  /* Misc. Xen vars */
   3.288 +  XN_HANDLE handle;
   3.289 +  
   3.290 +  evtchn_port_t event_channel;
   3.291 +  ULONG backend_state;
   3.292 +  KEVENT backend_event;
   3.293 +  UCHAR multicast_list[MULTICAST_LIST_MAX_SIZE][6];
   3.294 +  ULONG multicast_list_size;
   3.295 +  KDPC rxtx_dpc;
   3.296 +
   3.297 +  /* tx related - protected by tx_lock */
   3.298 +  KSPIN_LOCK tx_lock; /* always acquire rx_lock before tx_lock */
   3.299 +  LIST_ENTRY tx_waiting_pkt_list;
   3.300 +  netif_tx_sring_t *tx_sring;
   3.301 +  grant_ref_t tx_sring_gref;
   3.302 +  struct netif_tx_front_ring tx_ring;
   3.303 +  ULONG tx_ring_free;
   3.304 +  tx_shadow_t tx_shadows[NET_TX_RING_SIZE];
   3.305 +  ULONG tx_outstanding;
   3.306 +  ULONG tx_id_free;
   3.307 +  USHORT tx_id_list[NET_TX_RING_SIZE];
   3.308 +  NPAGED_LOOKASIDE_LIST tx_lookaside_list;
   3.309 +  KEVENT tx_idle_event;
   3.310 +
   3.311 +  /* rx_related - protected by rx_lock */
   3.312 +  KSPIN_LOCK rx_lock; /* always acquire rx_lock before tx_lock */
   3.313 +  netif_rx_sring_t *rx_sring;
   3.314 +  grant_ref_t rx_sring_gref;
   3.315 +  struct netif_rx_front_ring rx_ring;
   3.316 +  ULONG rx_id_free;
   3.317 +  packet_info_t *rxpi;
   3.318 +  #if NTDDI_VERSION < NTDDI_VISTA
   3.319 +  #else
   3.320 +  NDIS_HANDLE rx_nbl_pool;
   3.321 +  #endif
   3.322 +  NDIS_HANDLE rx_packet_pool;
   3.323 +  volatile LONG rx_pb_free;
   3.324 +  struct stack_state *rx_pb_stack;
   3.325 +  volatile LONG rx_hb_free;
   3.326 +  struct stack_state *rx_hb_stack;
   3.327 +  shared_buffer_t *rx_ring_pbs[NET_RX_RING_SIZE];
   3.328 +  /* Receive-ring batched refills. */
   3.329 +  ULONG rx_target;
   3.330 +  ULONG rx_max_target;
   3.331 +  ULONG rx_min_target;
   3.332 +  shared_buffer_t *rx_partial_buf;
   3.333 +  BOOLEAN rx_partial_extra_info_flag ;
   3.334 +  BOOLEAN rx_partial_more_data_flag;
   3.335 +  KEVENT rx_idle_event;
   3.336 +  /* how many packets are in the net stack atm */
   3.337 +  LONG rx_outstanding;
   3.338 +
   3.339 +
   3.340 +  /* config vars from registry */
   3.341 +  /* the frontend_* indicate our willingness to support */
   3.342 +  BOOLEAN frontend_sg_supported;
   3.343 +  BOOLEAN frontend_csum_supported;
   3.344 +  ULONG frontend_gso_value;
   3.345 +  ULONG frontend_mtu_value;
   3.346 +  ULONG frontend_gso_rx_split_type; /* RX_LSO_SPLIT_* */
   3.347 +
   3.348 +  BOOLEAN backend_sg_supported;
   3.349 +  BOOLEAN backend_csum_supported;
   3.350 +  ULONG backend_gso_value;
   3.351 +  
   3.352 +  BOOLEAN current_sg_supported;
   3.353 +  BOOLEAN current_csum_supported;
   3.354 +  ULONG current_gso_value;
   3.355 +  ULONG current_mtu_value;
   3.356 +  ULONG current_gso_rx_split_type;
   3.357 +
   3.358 +  BOOLEAN config_csum_rx_check;
   3.359 +  BOOLEAN config_csum_rx_dont_fix;
   3.360 +
   3.361 +  #if NTDDI_VERSION < NTDDI_VISTA
   3.362 +  NDIS_TASK_TCP_IP_CHECKSUM setting_csum;
   3.363 +  #else
   3.364 +  #endif
   3.365 +
   3.366 +  /* config stuff calculated from the above */
   3.367 +  ULONG config_max_pkt_size;
   3.368 +
   3.369 +  /* stats */
   3.370 +  #if NTDDI_VERSION < NTDDI_VISTA
   3.371 +  ULONG64 stat_tx_ok;
   3.372 +  ULONG64 stat_rx_ok;
   3.373 +  ULONG64 stat_tx_error;
   3.374 +  ULONG64 stat_rx_error;
   3.375 +  ULONG64 stat_rx_no_buffer;
   3.376 +  #else
   3.377 +  NDIS_STATISTICS_INFO stats;
   3.378 +  #endif
   3.379 +  
   3.380 +} typedef xennet_info_t;
   3.381 +
   3.382 +extern USHORT ndis_os_major_version;
   3.383 +extern USHORT ndis_os_minor_version;
   3.384 +
   3.385 +typedef NDIS_STATUS (*XEN_OID_REQUEST)(NDIS_HANDLE context, PVOID information_buffer, ULONG information_buffer_length, PULONG bytes_read, PULONG bytes_needed);
   3.386 +
   3.387 +struct xennet_oids_t {
   3.388 +  ULONG oid;
   3.389 +  char *oid_name;
   3.390 +  ULONG min_length;
   3.391 +  XEN_OID_REQUEST query_routine;
   3.392 +  XEN_OID_REQUEST set_routine;
   3.393 +};
   3.394 +
   3.395 +extern struct xennet_oids_t xennet_oids[];
   3.396 +
   3.397 +#if NTDDI_VERSION < NTDDI_VISTA
   3.398 +NDIS_STATUS
   3.399 +XenNet_QueryInformation(
   3.400 +  IN NDIS_HANDLE MiniportAdapterContext,
   3.401 +  IN NDIS_OID Oid,
   3.402 +  IN PVOID InformationBuffer,
   3.403 +  IN ULONG InformationBufferLength,
   3.404 +  OUT PULONG BytesWritten,
   3.405 +  OUT PULONG BytesNeeded);
   3.406 +
   3.407 +NDIS_STATUS
   3.408 +XenNet_SetInformation(
   3.409 +  IN NDIS_HANDLE MiniportAdapterContext,
   3.410 +  IN NDIS_OID Oid,
   3.411 +  IN PVOID InformationBuffer,
   3.412 +  IN ULONG InformationBufferLength,
   3.413 +  OUT PULONG BytesRead,
   3.414 +  OUT PULONG BytesNeeded
   3.415 +  );
   3.416 +
   3.417 +VOID
   3.418 +XenNet_SendPackets(
   3.419 +  IN NDIS_HANDLE MiniportAdapterContext,
   3.420 +  IN PPNDIS_PACKET PacketArray,
   3.421 +  IN UINT NumberOfPackets
   3.422 +  );
   3.423 +
   3.424 +VOID
   3.425 +XenNet_ReturnPacket(
   3.426 +  IN NDIS_HANDLE MiniportAdapterContext,
   3.427 +  IN PNDIS_PACKET Packet
   3.428 +  );
   3.429 +#else
   3.430 +
   3.431 +MINIPORT_OID_REQUEST XenNet_OidRequest;
   3.432 +MINIPORT_CANCEL_OID_REQUEST XenNet_CancelOidRequest;
   3.433 +
   3.434 +MINIPORT_SEND_NET_BUFFER_LISTS XenNet_SendNetBufferLists;
   3.435 +MINIPORT_CANCEL_SEND XenNet_CancelSend;
   3.436 +
   3.437 +MINIPORT_RETURN_NET_BUFFER_LISTS XenNet_ReturnNetBufferLists;
   3.438 +#endif
   3.439 +
   3.440 +NTSTATUS XenNet_Connect(PVOID context, BOOLEAN suspend);
   3.441 +NTSTATUS XenNet_Disconnect(PVOID context, BOOLEAN suspend);
   3.442 +VOID XenNet_DeviceCallback(PVOID context, ULONG callback_type, PVOID value);
   3.443 +
   3.444 +
   3.445 +BOOLEAN XenNet_RxInit(xennet_info_t *xi);
   3.446 +VOID XenNet_RxShutdown(xennet_info_t *xi);
   3.447 +BOOLEAN XenNet_RxBufferCheck(struct xennet_info *xi);
   3.448 +
   3.449 +BOOLEAN XenNet_TxInit(xennet_info_t *xi);
   3.450 +BOOLEAN XenNet_TxShutdown(xennet_info_t *xi);
   3.451 +VOID XenNet_TxBufferGC(struct xennet_info *xi, BOOLEAN dont_set_event);
   3.452 +
   3.453 +
   3.454 +/* return values */
   3.455 +#define PARSE_OK 0
   3.456 +#define PARSE_TOO_SMALL 1 /* first buffer is too small */
   3.457 +#define PARSE_UNKNOWN_TYPE 2
   3.458 +
   3.459 +BOOLEAN XenNet_BuildHeader(packet_info_t *pi, PVOID header, ULONG new_header_size);
   3.460 +VOID XenNet_ParsePacketHeader(packet_info_t *pi, PUCHAR buffer, ULONG min_header_size);
   3.461 +BOOLEAN XenNet_FilterAcceptPacket(struct xennet_info *xi, packet_info_t *pi);
   3.462 +
   3.463 +BOOLEAN XenNet_CheckIpHeaderSum(PUCHAR header, USHORT ip4_header_length);
   3.464 +VOID XenNet_SumIpHeader(PUCHAR header, USHORT ip4_header_length);
   3.465 +
   3.466 +static __forceinline VOID
   3.467 +XenNet_ClearPacketInfo(packet_info_t *pi) {
   3.468 +  RtlZeroMemory(pi, sizeof(packet_info_t) - FIELD_OFFSET(packet_info_t, header_data));
   3.469 +}
   3.470 +
   3.471 +/* Get some data from the current packet, but don't cross a page boundry. */
   3.472 +static __forceinline ULONG
   3.473 +XenNet_QueryData(packet_info_t *pi, ULONG length) {
   3.474 +  ULONG offset_in_page;
   3.475 +  
   3.476 +  if (length > MmGetMdlByteCount(pi->curr_mdl) - pi->curr_mdl_offset)
   3.477 +    length = MmGetMdlByteCount(pi->curr_mdl) - pi->curr_mdl_offset;
   3.478 +
   3.479 +  offset_in_page = (MmGetMdlByteOffset(pi->curr_mdl) + pi->curr_mdl_offset) & (PAGE_SIZE - 1);
   3.480 +  if (offset_in_page + length > PAGE_SIZE)
   3.481 +    length = PAGE_SIZE - offset_in_page;
   3.482 +  
   3.483 +  return length;
   3.484 +}
   3.485 +
   3.486 +/* Move the pointers forward by the given amount. No error checking is done.  */
   3.487 +static __forceinline VOID
   3.488 +XenNet_EatData(packet_info_t *pi, ULONG length) {
   3.489 +  pi->curr_mdl_offset += length;
   3.490 +  if (pi->curr_mdl_offset >= MmGetMdlByteCount(pi->curr_mdl)) {
   3.491 +    pi->curr_mdl_offset -= MmGetMdlByteCount(pi->curr_mdl);
   3.492 +#if NTDDI_VERSION < NTDDI_VISTA
   3.493 +    NdisGetNextBuffer(pi->curr_mdl, &pi->curr_mdl);
   3.494 +#else
   3.495 +    NdisGetNextMdl(pi->curr_mdl, &pi->curr_mdl);
   3.496 +#endif
   3.497 +  }
   3.498 +}
     4.1 --- a/xennet/xennet5.c	Sun Feb 10 23:12:03 2013 +1100
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,996 +0,0 @@
     4.4 -/*
     4.5 -PV Net Driver for Windows Xen HVM Domains
     4.6 -Copyright (C) 2007 James Harper
     4.7 -Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
     4.8 -
     4.9 -This program is free software; you can redistribute it and/or
    4.10 -modify it under the terms of the GNU General Public License
    4.11 -as published by the Free Software Foundation; either version 2
    4.12 -of the License, or (at your option) any later version.
    4.13 -
    4.14 -This program is distributed in the hope that it will be useful,
    4.15 -but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.16 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.17 -GNU General Public License for more details.
    4.18 -
    4.19 -You should have received a copy of the GNU General Public License
    4.20 -along with this program; if not, write to the Free Software
    4.21 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    4.22 -*/
    4.23 -
    4.24 -#include <stdlib.h>
    4.25 -#include <io/xenbus.h>
    4.26 -#include "xennet5.h"
    4.27 -
    4.28 -/* Not really necessary but keeps PREfast happy */
    4.29 -DRIVER_INITIALIZE DriverEntry;
    4.30 -static IO_WORKITEM_ROUTINE XenNet_ResumeWorkItem;
    4.31 -#if (VER_PRODUCTBUILD >= 7600)
    4.32 -static KDEFERRED_ROUTINE XenNet_SuspendResume;
    4.33 -static KDEFERRED_ROUTINE XenNet_RxTxDpc;
    4.34 -#endif
    4.35 -
    4.36 -#pragma NDIS_INIT_FUNCTION(DriverEntry)
    4.37 -
    4.38 -/* ----- BEGIN Other people's code --------- */
    4.39 -/* from linux/include/linux/ctype.h, used under GPLv2 */
    4.40 -#define _U      0x01    /* upper */
    4.41 -#define _L      0x02    /* lower */
    4.42 -#define _D      0x04    /* digit */
    4.43 -#define _C      0x08    /* cntrl */
    4.44 -#define _P      0x10    /* punct */
    4.45 -#define _S      0x20    /* white space (space/lf/tab) */
    4.46 -#define _X      0x40    /* hex digit */
    4.47 -#define _SP     0x80    /* hard space (0x20) */
    4.48 -
    4.49 -/* from linux/include/lib/ctype.c, used under GPLv2 */
    4.50 -unsigned char _ctype[] = {
    4.51 -_C,_C,_C,_C,_C,_C,_C,_C,                        /* 0-7 */
    4.52 -_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,         /* 8-15 */
    4.53 -_C,_C,_C,_C,_C,_C,_C,_C,                        /* 16-23 */
    4.54 -_C,_C,_C,_C,_C,_C,_C,_C,                        /* 24-31 */
    4.55 -_S|_SP,_P,_P,_P,_P,_P,_P,_P,                    /* 32-39 */
    4.56 -_P,_P,_P,_P,_P,_P,_P,_P,                        /* 40-47 */
    4.57 -_D,_D,_D,_D,_D,_D,_D,_D,                        /* 48-55 */
    4.58 -_D,_D,_P,_P,_P,_P,_P,_P,                        /* 56-63 */
    4.59 -_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,      /* 64-71 */
    4.60 -_U,_U,_U,_U,_U,_U,_U,_U,                        /* 72-79 */
    4.61 -_U,_U,_U,_U,_U,_U,_U,_U,                        /* 80-87 */
    4.62 -_U,_U,_U,_P,_P,_P,_P,_P,                        /* 88-95 */
    4.63 -_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,      /* 96-103 */
    4.64 -_L,_L,_L,_L,_L,_L,_L,_L,                        /* 104-111 */
    4.65 -_L,_L,_L,_L,_L,_L,_L,_L,                        /* 112-119 */
    4.66 -_L,_L,_L,_P,_P,_P,_P,_C,                        /* 120-127 */
    4.67 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 128-143 */
    4.68 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 144-159 */
    4.69 -_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
    4.70 -_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
    4.71 -_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
    4.72 -_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
    4.73 -_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
    4.74 -_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
    4.75 -
    4.76 -/* from linux/include/linux/ctype.h, used under GPLv2 */
    4.77 -#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
    4.78 -
    4.79 -#define isalnum(c)      ((__ismask(c)&(_U|_L|_D)) != 0)
    4.80 -#define isalpha(c)      ((__ismask(c)&(_U|_L)) != 0)
    4.81 -#define iscntrl(c)      ((__ismask(c)&(_C)) != 0)
    4.82 -#define isdigit(c)      ((__ismask(c)&(_D)) != 0)
    4.83 -#define isgraph(c)      ((__ismask(c)&(_P|_U|_L|_D)) != 0)
    4.84 -#define islower(c)      ((__ismask(c)&(_L)) != 0)
    4.85 -#define isprint(c)      ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
    4.86 -#define ispunct(c)      ((__ismask(c)&(_P)) != 0)
    4.87 -#define isspace(c)      ((__ismask(c)&(_S)) != 0)
    4.88 -#define isupper(c)      ((__ismask(c)&(_U)) != 0)
    4.89 -#define isxdigit(c)     ((__ismask(c)&(_D|_X)) != 0)
    4.90 -
    4.91 -#define TOLOWER(x) ((x) | 0x20)
    4.92 -
    4.93 -/* from linux/lib/vsprintf.c, used under GPLv2 */
    4.94 -/* Copyright (C) 1991, 1992  Linus Torvalds
    4.95 - * Wirzenius wrote this portably, Torvalds fucked it up :-)
    4.96 - */
    4.97 -/**
    4.98 - * simple_strtoul - convert a string to an unsigned long
    4.99 - * @cp: The start of the string
   4.100 - * @endp: A pointer to the end of the parsed string will be placed here
   4.101 - * @base: The number base to use
   4.102 - */
   4.103 -unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
   4.104 -{
   4.105 -  unsigned long result = 0,value;
   4.106 -
   4.107 -  if (!base) {
   4.108 -    base = 10;
   4.109 -    if (*cp == '0') {
   4.110 -      base = 8;
   4.111 -      cp++;
   4.112 -      if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) {
   4.113 -        cp++;
   4.114 -        base = 16;
   4.115 -      }
   4.116 -    }
   4.117 -  } else if (base == 16) {
   4.118 -    if (cp[0] == '0' && TOLOWER(cp[1]) == 'x')
   4.119 -      cp += 2;
   4.120 -  }
   4.121 -  while (isxdigit(*cp) &&
   4.122 -    (value = isdigit(*cp) ? *cp-'0' : TOLOWER(*cp)-'a'+10) < base) {
   4.123 -    result = result*base + value;
   4.124 -    cp++;
   4.125 -  }
   4.126 -  if (endp)
   4.127 -    *endp = (char *)cp;
   4.128 -  return result;
   4.129 -}
   4.130 -/* end vsprintf.c code */
   4.131 -/* ----- END Other people's code --------- */
   4.132 -
   4.133 -static NDIS_STATUS
   4.134 -XenNet_ConnectBackend(struct xennet_info *xi)
   4.135 -{
   4.136 -  PUCHAR ptr;
   4.137 -  UCHAR type;
   4.138 -  PCHAR setting, value, value2;
   4.139 -  UINT i;
   4.140 -  ULONG backend_sg = 0;
   4.141 -  ULONG backend_gso = 0;
   4.142 -
   4.143 -  FUNCTION_ENTER();
   4.144 -  
   4.145 -  ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
   4.146 -
   4.147 -  ptr = xi->config_page;
   4.148 -  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
   4.149 -  {
   4.150 -    switch(type)
   4.151 -    {
   4.152 -    case XEN_INIT_TYPE_RING: /* frontend ring */
   4.153 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
   4.154 -      if (strcmp(setting, "tx-ring-ref") == 0)
   4.155 -      {
   4.156 -        FRONT_RING_INIT(&xi->tx, (netif_tx_sring_t *)value, PAGE_SIZE);
   4.157 -      } else if (strcmp(setting, "rx-ring-ref") == 0)
   4.158 -      {
   4.159 -        FRONT_RING_INIT(&xi->rx, (netif_rx_sring_t *)value, PAGE_SIZE);
   4.160 -      }
   4.161 -      break;
   4.162 -    case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
   4.163 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value)));
   4.164 -      if (strcmp(setting, "event-channel") == 0)
   4.165 -      {
   4.166 -        xi->event_channel = PtrToUlong(value);
   4.167 -      }
   4.168 -      break;
   4.169 -    case XEN_INIT_TYPE_READ_STRING_FRONT:
   4.170 -      break;
   4.171 -    case XEN_INIT_TYPE_READ_STRING_BACK:
   4.172 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
   4.173 -      if (strcmp(setting, "mac") == 0)
   4.174 -      {
   4.175 -        char *s, *e;
   4.176 -        s = value;
   4.177 -        for (i = 0; i < ETH_ALEN; i++) {
   4.178 -          xi->perm_mac_addr[i] = (uint8_t)simple_strtoul(s, &e, 16);
   4.179 -          if ((s == e) || (*e != ((i == ETH_ALEN-1) ? '\0' : ':'))) {
   4.180 -            KdPrint((__DRIVER_NAME "Error parsing MAC address\n"));
   4.181 -          }
   4.182 -          s = e + 1;
   4.183 -        }
   4.184 -        if ((xi->curr_mac_addr[0] & 0x03) != 0x02)
   4.185 -        {
   4.186 -          /* only copy if curr_mac_addr is not a LUA */
   4.187 -          memcpy(xi->curr_mac_addr, xi->perm_mac_addr, ETH_ALEN);
   4.188 -        }
   4.189 -      }
   4.190 -      else if (strcmp(setting, "feature-sg") == 0)
   4.191 -      {
   4.192 -        if (atoi(value))
   4.193 -        {
   4.194 -          backend_sg = 1;
   4.195 -        }
   4.196 -      }
   4.197 -      else if (strcmp(setting, "feature-gso-tcpv4") == 0)
   4.198 -      {
   4.199 -        if (atoi(value))
   4.200 -        {
   4.201 -          backend_gso = 1;
   4.202 -        }
   4.203 -      }
   4.204 -      break;
   4.205 -    case XEN_INIT_TYPE_VECTORS:
   4.206 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
   4.207 -      if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
   4.208 -        ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
   4.209 -      {
   4.210 -        KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
   4.211 -          ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
   4.212 -        FUNCTION_EXIT();
   4.213 -        return NDIS_STATUS_ADAPTER_NOT_FOUND;
   4.214 -      }
   4.215 -      else
   4.216 -        memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS));
   4.217 -      break;
   4.218 -    case XEN_INIT_TYPE_STATE_PTR:
   4.219 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
   4.220 -      xi->device_state = (PXENPCI_DEVICE_STATE)value;
   4.221 -      break;
   4.222 -    default:
   4.223 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
   4.224 -      break;
   4.225 -    }
   4.226 -  }
   4.227 -  if (xi->config_sg && !backend_sg)
   4.228 -  {
   4.229 -    KdPrint((__DRIVER_NAME "     SG not supported by backend - disabling\n"));
   4.230 -    xi->config_sg = 0;
   4.231 -  }
   4.232 -  if (xi->config_gso && !backend_gso)
   4.233 -  {
   4.234 -    KdPrint((__DRIVER_NAME "     GSO not supported by backend - disabling\n"));
   4.235 -    xi->config_gso = 0;
   4.236 -  }
   4.237 -  FUNCTION_EXIT();
   4.238 -  
   4.239 -  return NDIS_STATUS_SUCCESS;
   4.240 -}
   4.241 -
   4.242 -static VOID
   4.243 -XenNet_ResumeWorkItem(PDEVICE_OBJECT device_object, PVOID context)
   4.244 -{
   4.245 -  struct xennet_info *xi = context;
   4.246 -  KIRQL old_irql;
   4.247 -  
   4.248 -  UNREFERENCED_PARAMETER(device_object);
   4.249 -  
   4.250 -  FUNCTION_ENTER();
   4.251 -
   4.252 -  ASSERT(xi->resume_work_item);
   4.253 -
   4.254 -  IoFreeWorkItem(xi->resume_work_item);
   4.255 -  
   4.256 -  XenNet_TxResumeStart(xi);
   4.257 -  XenNet_RxResumeStart(xi);
   4.258 -  XenNet_ConnectBackend(xi);
   4.259 -  XenNet_RxResumeEnd(xi);
   4.260 -  XenNet_TxResumeEnd(xi);
   4.261 -
   4.262 -  KeAcquireSpinLock(&xi->resume_lock, &old_irql);
   4.263 -  xi->resume_work_item = NULL;
   4.264 -  KdPrint((__DRIVER_NAME "     *Setting suspend_resume_state_fdo = %d\n", xi->device_state->suspend_resume_state_pdo));
   4.265 -  xi->device_state->suspend_resume_state_fdo = xi->device_state->suspend_resume_state_pdo;
   4.266 -  KdPrint((__DRIVER_NAME "     *Notifying event channel %d\n", xi->device_state->pdo_event_channel));
   4.267 -  xi->vectors.EvtChn_Notify(xi->vectors.context, xi->device_state->pdo_event_channel);
   4.268 -  KeReleaseSpinLock(&xi->resume_lock, old_irql);
   4.269 -
   4.270 -  FUNCTION_EXIT();
   4.271 -
   4.272 -}
   4.273 -
   4.274 -static VOID
   4.275 -XenNet_SuspendResume(PKDPC dpc, PVOID context, PVOID arg1, PVOID arg2)
   4.276 -{
   4.277 -  struct xennet_info *xi = context;
   4.278 -  KIRQL old_irql;
   4.279 -  PIO_WORKITEM resume_work_item;
   4.280 -
   4.281 -  UNREFERENCED_PARAMETER(dpc);
   4.282 -  UNREFERENCED_PARAMETER(arg1);
   4.283 -  UNREFERENCED_PARAMETER(arg2);
   4.284 -
   4.285 -  FUNCTION_ENTER();
   4.286 -  
   4.287 -  switch (xi->device_state->suspend_resume_state_pdo)
   4.288 -  {
   4.289 -  case SR_STATE_SUSPENDING:
   4.290 -    KdPrint((__DRIVER_NAME "     New state SUSPENDING\n"));
   4.291 -    KeAcquireSpinLock(&xi->rx_lock, &old_irql);
   4.292 -    if (xi->rx_id_free == NET_RX_RING_SIZE)
   4.293 -    {  
   4.294 -      xi->device_state->suspend_resume_state_fdo = SR_STATE_SUSPENDING;
   4.295 -      KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xi->device_state->pdo_event_channel));
   4.296 -      xi->vectors.EvtChn_Notify(xi->vectors.context, xi->device_state->pdo_event_channel);
   4.297 -    }
   4.298 -    KeReleaseSpinLock(&xi->rx_lock, old_irql);
   4.299 -    break;
   4.300 -  case SR_STATE_RESUMING:
   4.301 -    KdPrint((__DRIVER_NAME "     New state SR_STATE_RESUMING\n"));
   4.302 -    /* do it like this so we don't race and double-free the work item */
   4.303 -    resume_work_item = IoAllocateWorkItem(xi->fdo);
   4.304 -    KeAcquireSpinLock(&xi->resume_lock, &old_irql);
   4.305 -    if (xi->resume_work_item || xi->device_state->suspend_resume_state_fdo == SR_STATE_RESUMING)
   4.306 -    {
   4.307 -      KeReleaseSpinLock(&xi->resume_lock, old_irql);
   4.308 -      IoFreeWorkItem(resume_work_item);
   4.309 -      return;
   4.310 -    }
   4.311 -    xi->resume_work_item = resume_work_item;
   4.312 -    KeReleaseSpinLock(&xi->resume_lock, old_irql);
   4.313 -    IoQueueWorkItem(xi->resume_work_item, XenNet_ResumeWorkItem, DelayedWorkQueue, xi);
   4.314 -    break;
   4.315 -  default:
   4.316 -    KdPrint((__DRIVER_NAME "     New state %d\n", xi->device_state->suspend_resume_state_fdo));
   4.317 -    xi->device_state->suspend_resume_state_fdo = xi->device_state->suspend_resume_state_pdo;
   4.318 -    KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xi->device_state->pdo_event_channel));
   4.319 -    xi->vectors.EvtChn_Notify(xi->vectors.context, xi->device_state->pdo_event_channel);
   4.320 -    break;
   4.321 -  }
   4.322 -  KeMemoryBarrier();
   4.323 -  
   4.324 -  FUNCTION_EXIT();
   4.325 -}
   4.326 -
   4.327 -static VOID
   4.328 -XenNet_RxTxDpc(PKDPC dpc, PVOID context, PVOID arg1, PVOID arg2)
   4.329 -{
   4.330 -  struct xennet_info *xi = context;
   4.331 -  BOOLEAN dont_set_event;
   4.332 -
   4.333 -  UNREFERENCED_PARAMETER(dpc);
   4.334 -  UNREFERENCED_PARAMETER(arg1);
   4.335 -  UNREFERENCED_PARAMETER(arg2);
   4.336 -
   4.337 -  /* 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 */
   4.338 -  dont_set_event = XenNet_RxBufferCheck(xi);
   4.339 -  XenNet_TxBufferGC(xi, dont_set_event);
   4.340 -} 
   4.341 -
   4.342 -static BOOLEAN
   4.343 -XenNet_HandleEvent(PVOID context)
   4.344 -{
   4.345 -  struct xennet_info *xi = context;
   4.346 -  ULONG suspend_resume_state_pdo;
   4.347 -  
   4.348 -  //FUNCTION_ENTER();
   4.349 -  suspend_resume_state_pdo = xi->device_state->suspend_resume_state_pdo;
   4.350 -  KeMemoryBarrier();
   4.351 -//  KdPrint((__DRIVER_NAME "     connected = %d, inactive = %d, suspend_resume_state_pdo = %d\n",
   4.352 -//    xi->connected, xi->inactive, suspend_resume_state_pdo));
   4.353 -  if (!xi->shutting_down && suspend_resume_state_pdo != xi->device_state->suspend_resume_state_fdo)
   4.354 -  {
   4.355 -    KeInsertQueueDpc(&xi->suspend_dpc, NULL, NULL);
   4.356 -  }
   4.357 -  if (xi->connected && !xi->inactive && suspend_resume_state_pdo != SR_STATE_RESUMING)
   4.358 -  {
   4.359 -    KeInsertQueueDpc(&xi->rxtx_dpc, NULL, NULL);
   4.360 -  }
   4.361 -  //FUNCTION_EXIT();
   4.362 -  return TRUE;
   4.363 -}
   4.364 -
   4.365 -VOID
   4.366 -XenNet_SetPower(PDEVICE_OBJECT device_object, PVOID context)
   4.367 -{
   4.368 -  NTSTATUS status = STATUS_SUCCESS;
   4.369 -  KIRQL old_irql;
   4.370 -  struct xennet_info *xi = context;
   4.371 -  
   4.372 -  FUNCTION_ENTER();
   4.373 -  UNREFERENCED_PARAMETER(device_object);
   4.374 -
   4.375 -  switch (xi->new_power_state)
   4.376 -  {
   4.377 -  case NdisDeviceStateD0:
   4.378 -    KdPrint(("       NdisDeviceStateD0\n"));
   4.379 -    status = XenNet_D0Entry(xi);
   4.380 -    break;
   4.381 -  case NdisDeviceStateD1:
   4.382 -    KdPrint(("       NdisDeviceStateD1\n"));
   4.383 -    if (xi->power_state == NdisDeviceStateD0)
   4.384 -      status = XenNet_D0Exit(xi);
   4.385 -    break;
   4.386 -  case NdisDeviceStateD2:
   4.387 -    KdPrint(("       NdisDeviceStateD2\n"));
   4.388 -    if (xi->power_state == NdisDeviceStateD0)
   4.389 -      status = XenNet_D0Exit(xi);
   4.390 -    break;
   4.391 -  case NdisDeviceStateD3:
   4.392 -    KdPrint(("       NdisDeviceStateD3\n"));
   4.393 -    if (xi->power_state == NdisDeviceStateD0)
   4.394 -      status = XenNet_D0Exit(xi);
   4.395 -    break;
   4.396 -  default:
   4.397 -    KdPrint(("       NdisDeviceState??\n"));
   4.398 -    status = NDIS_STATUS_NOT_SUPPORTED;
   4.399 -    break;
   4.400 -  }
   4.401 -  xi->power_state = xi->new_power_state;
   4.402 -
   4.403 -  old_irql = KeRaiseIrqlToDpcLevel();
   4.404 -  NdisMSetInformationComplete(xi->adapter_handle, status);
   4.405 -  KeLowerIrql(old_irql);
   4.406 -  
   4.407 -  FUNCTION_EXIT();
   4.408 -}
   4.409 -
   4.410 -NDIS_STATUS
   4.411 -XenNet_D0Entry(struct xennet_info *xi)
   4.412 -{
   4.413 -  NDIS_STATUS status;
   4.414 -  PUCHAR ptr;
   4.415 -  CHAR buf[128];
   4.416 -  
   4.417 -  FUNCTION_ENTER();
   4.418 -
   4.419 -  xi->shutting_down = FALSE;
   4.420 -  
   4.421 -  ptr = xi->config_page;
   4.422 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "tx-ring-ref", NULL, NULL);
   4.423 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "rx-ring-ref", NULL, NULL);
   4.424 -  #pragma warning(suppress:4054)
   4.425 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL, "event-channel", (PVOID)XenNet_HandleEvent, xi);
   4.426 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "mac", NULL, NULL);
   4.427 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "feature-sg", NULL, NULL);
   4.428 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "feature-gso-tcpv4", NULL, NULL);
   4.429 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "request-rx-copy", "1", NULL);
   4.430 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-rx-notify", "1", NULL);
   4.431 -  RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "%d", !xi->config_csum);
   4.432 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-no-csum-offload", buf, NULL);
   4.433 -  RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "%d", (int)xi->config_sg);
   4.434 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-sg", buf, NULL);
   4.435 -  RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "%d", !!xi->config_gso);
   4.436 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-gso-tcpv4", buf, NULL);
   4.437 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_PRE_CONNECT, NULL, NULL, NULL);
   4.438 -  __ADD_XEN_INIT_UCHAR(&ptr, 0); /* no pre-connect required */
   4.439 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_POST_CONNECT, NULL, NULL, NULL);
   4.440 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
   4.441 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
   4.442 -  __ADD_XEN_INIT_UCHAR(&ptr, 20);
   4.443 -  __ADD_XEN_INIT_UCHAR(&ptr, 0);
   4.444 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_SHUTDOWN, NULL, NULL, NULL);
   4.445 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
   4.446 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
   4.447 -  __ADD_XEN_INIT_UCHAR(&ptr, 50);
   4.448 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
   4.449 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
   4.450 -  __ADD_XEN_INIT_UCHAR(&ptr, 50);
   4.451 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitialising);
   4.452 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitWait);
   4.453 -  __ADD_XEN_INIT_UCHAR(&ptr, 50);
   4.454 -  __ADD_XEN_INIT_UCHAR(&ptr, 0);
   4.455 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
   4.456 -
   4.457 -  status = xi->vectors.XenPci_XenConfigDevice(xi->vectors.context);
   4.458 -  if (!NT_SUCCESS(status))
   4.459 -  {
   4.460 -    KdPrint(("Failed to complete device configuration (%08x)\n", status));
   4.461 -    return status;
   4.462 -  }
   4.463 -
   4.464 -  status = XenNet_ConnectBackend(xi);
   4.465 -  
   4.466 -  if (!NT_SUCCESS(status))
   4.467 -  {
   4.468 -    KdPrint(("Failed to complete device configuration (%08x)\n", status));
   4.469 -    return status;
   4.470 -  }
   4.471 -
   4.472 -  if (!xi->config_sg)
   4.473 -  {
   4.474 -    /* without SG, GSO can be a maximum of PAGE_SIZE */
   4.475 -    xi->config_gso = min(xi->config_gso, PAGE_SIZE);
   4.476 -  }
   4.477 -
   4.478 -  XenNet_TxInit(xi);
   4.479 -  XenNet_RxInit(xi);
   4.480 -
   4.481 -  xi->connected = TRUE;
   4.482 -
   4.483 -  KeMemoryBarrier(); // packets could be received anytime after we set Frontent to Connected
   4.484 -
   4.485 -  FUNCTION_EXIT();
   4.486 -
   4.487 -  return status;
   4.488 -}
   4.489 -
   4.490 -// Called at <= DISPATCH_LEVEL
   4.491 -static NDIS_STATUS
   4.492 -XenNet_Init(
   4.493 -  OUT PNDIS_STATUS OpenErrorStatus,
   4.494 -  OUT PUINT SelectedMediumIndex,
   4.495 -  IN PNDIS_MEDIUM MediumArray,
   4.496 -  IN UINT MediumArraySize,
   4.497 -  IN NDIS_HANDLE MiniportAdapterHandle,
   4.498 -  IN NDIS_HANDLE WrapperConfigurationContext
   4.499 -  )
   4.500 -{
   4.501 -  NDIS_STATUS status;
   4.502 -  BOOLEAN medium_found = FALSE;
   4.503 -  struct xennet_info *xi = NULL;
   4.504 -  UINT nrl_length;
   4.505 -  PNDIS_RESOURCE_LIST nrl;
   4.506 -  PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
   4.507 -  KIRQL irq_level = 0;
   4.508 -  ULONG irq_vector = 0;
   4.509 -  ULONG irq_mode = 0;
   4.510 -  NDIS_HANDLE config_handle;
   4.511 -  NDIS_STRING config_param_name;
   4.512 -  PNDIS_CONFIGURATION_PARAMETER config_param;
   4.513 -  ULONG i;
   4.514 -  PUCHAR ptr;
   4.515 -  UCHAR type;
   4.516 -  PCHAR setting, value;
   4.517 -  ULONG length;
   4.518 -  //CHAR buf[128];
   4.519 -  PVOID network_address;
   4.520 -  UINT network_address_length;
   4.521 -  BOOLEAN qemu_hide_filter = FALSE;
   4.522 -  ULONG qemu_hide_flags_value = 0;
   4.523 -  
   4.524 -  UNREFERENCED_PARAMETER(OpenErrorStatus);
   4.525 -
   4.526 -  FUNCTION_ENTER();
   4.527 -
   4.528 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   4.529 -
   4.530 -  /* deal with medium stuff */
   4.531 -  for (i = 0; i < MediumArraySize; i++)
   4.532 -  {
   4.533 -    if (MediumArray[i] == NdisMedium802_3)
   4.534 -    {
   4.535 -      medium_found = TRUE;
   4.536 -      break;
   4.537 -    }
   4.538 -  }
   4.539 -  if (!medium_found)
   4.540 -  {
   4.541 -    KdPrint(("NIC_MEDIA_TYPE not in MediumArray\n"));
   4.542 -    return NDIS_STATUS_UNSUPPORTED_MEDIA;
   4.543 -  }
   4.544 -  *SelectedMediumIndex = i;
   4.545 -
   4.546 -  /* Alloc memory for adapter private info */
   4.547 -  status = NdisAllocateMemoryWithTag((PVOID)&xi, sizeof(*xi), XENNET_POOL_TAG);
   4.548 -  if (!NT_SUCCESS(status))
   4.549 -  {
   4.550 -    KdPrint(("NdisAllocateMemoryWithTag failed with 0x%x\n", status));
   4.551 -    status = NDIS_STATUS_RESOURCES;
   4.552 -    goto err;
   4.553 -  }
   4.554 -  RtlZeroMemory(xi, sizeof(*xi));
   4.555 -  xi->adapter_handle = MiniportAdapterHandle;
   4.556 -  xi->rx_target     = RX_DFL_MIN_TARGET;
   4.557 -  xi->rx_min_target = RX_DFL_MIN_TARGET;
   4.558 -  xi->rx_max_target = RX_MAX_TARGET;
   4.559 -  xi->inactive      = TRUE;
   4.560 -  NdisMSetAttributesEx(xi->adapter_handle, (NDIS_HANDLE) xi, 0, 0 /* the last zero is to give the next | something to | with */
   4.561 -#ifdef NDIS51_MINIPORT
   4.562 -    |NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS
   4.563 -#endif
   4.564 -    |NDIS_ATTRIBUTE_DESERIALIZE
   4.565 -    |NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK,
   4.566 -    NdisInterfaceInternal); /* PnpBus option doesn't exist... */
   4.567 -  xi->multicast_list_size = 0;
   4.568 -  xi->current_lookahead = MIN_LOOKAHEAD_LENGTH;
   4.569 -
   4.570 -  nrl_length = 0;
   4.571 -  NdisMQueryAdapterResources(&status, WrapperConfigurationContext,
   4.572 -    NULL, (PUINT)&nrl_length);
   4.573 -  KdPrint((__DRIVER_NAME "     nrl_length = %d\n", nrl_length));
   4.574 -  status = NdisAllocateMemoryWithTag((PVOID)&nrl, nrl_length, XENNET_POOL_TAG);
   4.575 -  if (status != NDIS_STATUS_SUCCESS)
   4.576 -  {
   4.577 -    KdPrint((__DRIVER_NAME "     Could not get allocate memory for Adapter Resources 0x%x\n", status));
   4.578 -    return NDIS_STATUS_RESOURCES;
   4.579 -  }
   4.580 -  NdisMQueryAdapterResources(&status, WrapperConfigurationContext,
   4.581 -    nrl, (PUINT)&nrl_length);
   4.582 -  if (status != NDIS_STATUS_SUCCESS)
   4.583 -  {
   4.584 -    KdPrint((__DRIVER_NAME "     Could not get Adapter Resources 0x%x\n", status));
   4.585 -    return NDIS_STATUS_RESOURCES;
   4.586 -  }
   4.587 -  xi->event_channel = 0;
   4.588 -  xi->config_csum = 1;
   4.589 -  xi->config_csum_rx_check = 1;
   4.590 -  xi->config_sg = 1;
   4.591 -  xi->config_gso = 61440;
   4.592 -  xi->config_page = NULL;
   4.593 -  xi->config_rx_interrupt_moderation = 0;
   4.594 -  
   4.595 -  for (i = 0; i < nrl->Count; i++)
   4.596 -  {
   4.597 -    prd = &nrl->PartialDescriptors[i];
   4.598 -
   4.599 -    switch(prd->Type)
   4.600 -    {
   4.601 -    case CmResourceTypeInterrupt:
   4.602 -      irq_vector = prd->u.Interrupt.Vector;
   4.603 -      irq_level = (KIRQL)prd->u.Interrupt.Level;
   4.604 -      irq_mode = (prd->Flags & CM_RESOURCE_INTERRUPT_LATCHED)?NdisInterruptLatched:NdisInterruptLevelSensitive;
   4.605 -      KdPrint((__DRIVER_NAME "     irq_vector = %03x, irq_level = %03x, irq_mode = %s\n", irq_vector, irq_level,
   4.606 -        (irq_mode == NdisInterruptLatched)?"NdisInterruptLatched":"NdisInterruptLevelSensitive"));
   4.607 -      break;
   4.608 -    case CmResourceTypeMemory:
   4.609 -      if (xi->config_page)
   4.610 -      {
   4.611 -        KdPrint(("More than one memory range\n"));
   4.612 -        return NDIS_STATUS_RESOURCES;
   4.613 -      }
   4.614 -      else
   4.615 -      {
   4.616 -        status = NdisMMapIoSpace(&xi->config_page, MiniportAdapterHandle, prd->u.Memory.Start, prd->u.Memory.Length);
   4.617 -        if (!NT_SUCCESS(status))
   4.618 -        {
   4.619 -          KdPrint(("NdisMMapIoSpace failed with 0x%x\n", status));
   4.620 -          NdisFreeMemory(nrl, nrl_length, 0);
   4.621 -          return NDIS_STATUS_RESOURCES;
   4.622 -        }
   4.623 -      }
   4.624 -      break;
   4.625 -    }
   4.626 -  }
   4.627 -  NdisFreeMemory(nrl, nrl_length, 0);
   4.628 -  if (!xi->config_page)
   4.629 -  {
   4.630 -    KdPrint(("No config page given\n"));
   4.631 -    return NDIS_STATUS_RESOURCES;
   4.632 -  }
   4.633 -
   4.634 -  KeInitializeDpc(&xi->suspend_dpc, XenNet_SuspendResume, xi);
   4.635 -  KeInitializeSpinLock(&xi->resume_lock);
   4.636 -
   4.637 -  KeInitializeDpc(&xi->rxtx_dpc, XenNet_RxTxDpc, xi);
   4.638 -  KeSetTargetProcessorDpc(&xi->rxtx_dpc, 0);
   4.639 -  KeSetImportanceDpc(&xi->rxtx_dpc, HighImportance);
   4.640 -
   4.641 -  NdisMGetDeviceProperty(MiniportAdapterHandle, &xi->pdo, &xi->fdo,
   4.642 -    &xi->lower_do, NULL, NULL);
   4.643 -  xi->packet_filter = 0;
   4.644 -
   4.645 -  status = IoGetDeviceProperty(xi->pdo, DevicePropertyDeviceDescription,
   4.646 -    NAME_SIZE, xi->dev_desc, &length);
   4.647 -  if (!NT_SUCCESS(status))
   4.648 -  {
   4.649 -    KdPrint(("IoGetDeviceProperty failed with 0x%x\n", status));
   4.650 -    status = NDIS_STATUS_FAILURE;
   4.651 -    goto err;
   4.652 -  }
   4.653 -
   4.654 -  ptr = xi->config_page;
   4.655 -  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value)) != XEN_INIT_TYPE_END)
   4.656 -  {
   4.657 -    switch(type)
   4.658 -    {
   4.659 -    case XEN_INIT_TYPE_VECTORS:
   4.660 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
   4.661 -      if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
   4.662 -        ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
   4.663 -      {
   4.664 -        KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
   4.665 -          ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
   4.666 -        FUNCTION_EXIT();
   4.667 -        return NDIS_STATUS_FAILURE;
   4.668 -      }
   4.669 -      else
   4.670 -        memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS));
   4.671 -      break;
   4.672 -    case XEN_INIT_TYPE_STATE_PTR:
   4.673 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
   4.674 -      xi->device_state = (PXENPCI_DEVICE_STATE)value;
   4.675 -      break;
   4.676 -    case XEN_INIT_TYPE_QEMU_HIDE_FLAGS:
   4.677 -      qemu_hide_flags_value = PtrToUlong(value);
   4.678 -      break;
   4.679 -    case XEN_INIT_TYPE_QEMU_HIDE_FILTER:
   4.680 -      qemu_hide_filter = TRUE;
   4.681 -      break;
   4.682 -    default:
   4.683 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
   4.684 -      break;
   4.685 -    }
   4.686 -  }
   4.687 -
   4.688 -  if ((qemu_hide_flags_value & QEMU_UNPLUG_ALL_IDE_DISKS) || qemu_hide_filter)
   4.689 -    xi->inactive = FALSE;
   4.690 -
   4.691 -  xi->power_state = NdisDeviceStateD0;
   4.692 -  xi->power_workitem = IoAllocateWorkItem(xi->fdo);
   4.693 -
   4.694 -  // now build config page
   4.695 -  
   4.696 -  NdisOpenConfiguration(&status, &config_handle, WrapperConfigurationContext);
   4.697 -  if (!NT_SUCCESS(status))
   4.698 -  {
   4.699 -    KdPrint(("Could not open config in registry (%08x)\n", status));
   4.700 -    status = NDIS_STATUS_RESOURCES;
   4.701 -    goto err;
   4.702 -  }
   4.703 -
   4.704 -  NdisInitUnicodeString(&config_param_name, L"ScatterGather");
   4.705 -  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
   4.706 -  if (!NT_SUCCESS(status))
   4.707 -  {
   4.708 -    KdPrint(("Could not read ScatterGather value (%08x)\n", status));
   4.709 -    xi->config_sg = 1;
   4.710 -  }
   4.711 -  else
   4.712 -  {
   4.713 -    KdPrint(("ScatterGather = %d\n", config_param->ParameterData.IntegerData));
   4.714 -    xi->config_sg = config_param->ParameterData.IntegerData;
   4.715 -  }
   4.716 -  
   4.717 -  NdisInitUnicodeString(&config_param_name, L"LargeSendOffload");
   4.718 -  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
   4.719 -  if (!NT_SUCCESS(status))
   4.720 -  {
   4.721 -    KdPrint(("Could not read LargeSendOffload value (%08x)\n", status));
   4.722 -    xi->config_gso = 0;
   4.723 -  }
   4.724 -  else
   4.725 -  {
   4.726 -    KdPrint(("LargeSendOffload = %d\n", config_param->ParameterData.IntegerData));
   4.727 -    xi->config_gso = config_param->ParameterData.IntegerData;
   4.728 -    if (xi->config_gso > 61440)
   4.729 -    {
   4.730 -      xi->config_gso = 61440;
   4.731 -      KdPrint(("(clipped to %d)\n", xi->config_gso));
   4.732 -    }
   4.733 -  }
   4.734 -
   4.735 -  NdisInitUnicodeString(&config_param_name, L"ChecksumOffload");
   4.736 -  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
   4.737 -  if (!NT_SUCCESS(status))
   4.738 -  {
   4.739 -    KdPrint(("Could not read ChecksumOffload value (%08x)\n", status));
   4.740 -    xi->config_csum = 1;
   4.741 -  }
   4.742 -  else
   4.743 -  {
   4.744 -    KdPrint(("ChecksumOffload = %d\n", config_param->ParameterData.IntegerData));
   4.745 -    xi->config_csum = !!config_param->ParameterData.IntegerData;
   4.746 -  }
   4.747 -
   4.748 -  NdisInitUnicodeString(&config_param_name, L"ChecksumOffloadRxCheck");
   4.749 -  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
   4.750 -  if (!NT_SUCCESS(status))
   4.751 -  {
   4.752 -    KdPrint(("Could not read ChecksumOffloadRxCheck value (%08x)\n", status));
   4.753 -    xi->config_csum_rx_check = 1;
   4.754 -  }
   4.755 -  else
   4.756 -  {
   4.757 -    KdPrint(("ChecksumOffloadRxCheck = %d\n", config_param->ParameterData.IntegerData));
   4.758 -    xi->config_csum_rx_check = !!config_param->ParameterData.IntegerData;
   4.759 -  }
   4.760 -
   4.761 -  NdisInitUnicodeString(&config_param_name, L"ChecksumOffloadDontFix");
   4.762 -  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
   4.763 -  if (!NT_SUCCESS(status))
   4.764 -  {
   4.765 -    KdPrint(("Could not read ChecksumOffloadDontFix value (%08x)\n", status));
   4.766 -    xi->config_csum_rx_dont_fix = 0;
   4.767 -  }
   4.768 -  else
   4.769 -  {
   4.770 -    KdPrint(("ChecksumOffloadDontFix = %d\n", config_param->ParameterData.IntegerData));
   4.771 -    xi->config_csum_rx_dont_fix = !!config_param->ParameterData.IntegerData;
   4.772 -  }
   4.773 -  
   4.774 -  
   4.775 -  
   4.776 -  NdisInitUnicodeString(&config_param_name, L"MTU");
   4.777 -  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);  
   4.778 -  if (!NT_SUCCESS(status))
   4.779 -  {
   4.780 -    KdPrint(("Could not read MTU value (%08x)\n", status));
   4.781 -    xi->config_mtu = 1500;
   4.782 -  }
   4.783 -  else
   4.784 -  {
   4.785 -    KdPrint(("MTU = %d\n", config_param->ParameterData.IntegerData));
   4.786 -    xi->config_mtu = config_param->ParameterData.IntegerData;
   4.787 -  }
   4.788 -
   4.789 -  NdisInitUnicodeString(&config_param_name, L"RxInterruptModeration");
   4.790 -  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);  
   4.791 -  if (!NT_SUCCESS(status))
   4.792 -  {
   4.793 -    KdPrint(("Could not read RxInterruptModeration value (%08x)\n", status));
   4.794 -    xi->config_rx_interrupt_moderation = 1500;
   4.795 -  }
   4.796 -  else
   4.797 -  {
   4.798 -    KdPrint(("RxInterruptModeration = %d\n", config_param->ParameterData.IntegerData));
   4.799 -    xi->config_rx_interrupt_moderation = config_param->ParameterData.IntegerData;
   4.800 -  }
   4.801 -  
   4.802 -
   4.803 -  NdisReadNetworkAddress(&status, &network_address, &network_address_length, config_handle);
   4.804 -  if (!NT_SUCCESS(status) || network_address_length != ETH_ALEN || ((((PUCHAR)network_address)[0] & 0x03) != 0x02))
   4.805 -  {
   4.806 -    KdPrint(("Could not read NetworkAddress value (%08x) or value is invalid\n", status));
   4.807 -    memset(xi->curr_mac_addr, 0, ETH_ALEN);
   4.808 -  }
   4.809 -  else
   4.810 -  {
   4.811 -    memcpy(xi->curr_mac_addr, network_address, ETH_ALEN);
   4.812 -    KdPrint(("     Set MAC address from registry to %02X:%02X:%02X:%02X:%02X:%02X\n",
   4.813 -      xi->curr_mac_addr[0], xi->curr_mac_addr[1], xi->curr_mac_addr[2], 
   4.814 -      xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5]));
   4.815 -  }
   4.816 -
   4.817 -  xi->config_max_pkt_size = max(xi->config_mtu + XN_HDR_SIZE, xi->config_gso + XN_HDR_SIZE);
   4.818 -  
   4.819 -  NdisCloseConfiguration(config_handle);
   4.820 -
   4.821 -  status = XenNet_D0Entry(xi);
   4.822 -  if (!NT_SUCCESS(status))
   4.823 -  {
   4.824 -    KdPrint(("Failed to go to D0 (%08x)\n", status));
   4.825 -    goto err;
   4.826 -  }
   4.827 -  return NDIS_STATUS_SUCCESS;
   4.828 -  
   4.829 -err:
   4.830 -  NdisFreeMemory(xi, 0, 0);
   4.831 -  *OpenErrorStatus = status;
   4.832 -  FUNCTION_EXIT_STATUS(status);
   4.833 -  return status;
   4.834 -}
   4.835 -
   4.836 -VOID
   4.837 -XenNet_PnPEventNotify(
   4.838 -  IN NDIS_HANDLE MiniportAdapterContext,
   4.839 -  IN NDIS_DEVICE_PNP_EVENT PnPEvent,
   4.840 -  IN PVOID InformationBuffer,
   4.841 -  IN ULONG InformationBufferLength
   4.842 -  )
   4.843 -{
   4.844 -  UNREFERENCED_PARAMETER(MiniportAdapterContext);
   4.845 -  UNREFERENCED_PARAMETER(PnPEvent);
   4.846 -  UNREFERENCED_PARAMETER(InformationBuffer);
   4.847 -  UNREFERENCED_PARAMETER(InformationBufferLength);
   4.848 -
   4.849 -  FUNCTION_ENTER();
   4.850 -  switch (PnPEvent)
   4.851 -  {
   4.852 -  case NdisDevicePnPEventSurpriseRemoved:
   4.853 -    KdPrint((__DRIVER_NAME "     NdisDevicePnPEventSurpriseRemoved\n"));
   4.854 -    break;
   4.855 -  case NdisDevicePnPEventPowerProfileChanged :
   4.856 -    KdPrint((__DRIVER_NAME "     NdisDevicePnPEventPowerProfileChanged\n"));
   4.857 -    break;
   4.858 -  default:
   4.859 -    KdPrint((__DRIVER_NAME "     %d\n", PnPEvent));
   4.860 -    break;
   4.861 -  }
   4.862 -  FUNCTION_EXIT();
   4.863 -}
   4.864 -
   4.865 -/* Called when machine is shutting down, so just quiesce the HW and be done fast. */
   4.866 -VOID
   4.867 -XenNet_Shutdown(
   4.868 -  IN NDIS_HANDLE MiniportAdapterContext
   4.869 -  )
   4.870 -{
   4.871 -  UNREFERENCED_PARAMETER(MiniportAdapterContext);
   4.872 -
   4.873 -  /* remember we are called at >= DIRQL here */
   4.874 -  FUNCTION_ENTER();
   4.875 -  FUNCTION_EXIT();
   4.876 -}
   4.877 -
   4.878 -/* Opposite of XenNet_Init */
   4.879 -VOID
   4.880 -XenNet_Halt(
   4.881 -  IN NDIS_HANDLE MiniportAdapterContext
   4.882 -  )
   4.883 -{
   4.884 -  struct xennet_info *xi = MiniportAdapterContext;
   4.885 -
   4.886 -  FUNCTION_ENTER();
   4.887 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   4.888 -  
   4.889 -  XenNet_D0Exit(xi);
   4.890 -
   4.891 -  NdisFreeMemory(xi, 0, 0);
   4.892 -
   4.893 -  FUNCTION_EXIT();
   4.894 -}
   4.895 -
   4.896 -NDIS_STATUS
   4.897 -XenNet_D0Exit(struct xennet_info *xi)
   4.898 -{
   4.899 -  FUNCTION_ENTER();
   4.900 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   4.901 -
   4.902 -  xi->shutting_down = TRUE;
   4.903 -  KeMemoryBarrier(); /* make sure everyone sees that we are now shutting down */
   4.904 -
   4.905 -  XenNet_TxShutdown(xi);
   4.906 -  XenNet_RxShutdown(xi);
   4.907 -
   4.908 -  xi->connected = FALSE;
   4.909 -  KeMemoryBarrier(); /* make sure everyone sees that we are now disconnected */
   4.910 -
   4.911 -  xi->vectors.XenPci_XenShutdownDevice(xi->vectors.context);
   4.912 -
   4.913 -  FUNCTION_EXIT();
   4.914 -  
   4.915 -  return STATUS_SUCCESS;
   4.916 -}
   4.917 -
   4.918 -NDIS_STATUS 
   4.919 -XenNet_Reset(
   4.920 -  PBOOLEAN  AddressingReset,
   4.921 -  NDIS_HANDLE  MiniportAdapterContext
   4.922 -)
   4.923 -{
   4.924 -  UNREFERENCED_PARAMETER(MiniportAdapterContext);
   4.925 -
   4.926 -  *AddressingReset = FALSE;
   4.927 -  return NDIS_STATUS_SUCCESS;
   4.928 -}
   4.929 -
   4.930 -NTSTATUS
   4.931 -DriverEntry(
   4.932 -  PDRIVER_OBJECT DriverObject,
   4.933 -  PUNICODE_STRING RegistryPath
   4.934 -  )
   4.935 -{
   4.936 -  NTSTATUS status;  
   4.937 -  NDIS_HANDLE ndis_wrapper_handle = NULL;
   4.938 -  NDIS_MINIPORT_CHARACTERISTICS mini_chars;
   4.939 -
   4.940 -  FUNCTION_ENTER();
   4.941 -
   4.942 -  KdPrint((__DRIVER_NAME "     DriverObject = %p, RegistryPath = %p\n", DriverObject, RegistryPath));
   4.943 -  
   4.944 -  NdisZeroMemory(&mini_chars, sizeof(mini_chars));
   4.945 -
   4.946 -  KdPrint((__DRIVER_NAME "     NdisGetVersion = %x\n", NdisGetVersion()));
   4.947 -
   4.948 -  KdPrint((__DRIVER_NAME "     ndis_wrapper_handle = %p\n", ndis_wrapper_handle));
   4.949 -  NdisMInitializeWrapper(&ndis_wrapper_handle, DriverObject, RegistryPath, NULL);
   4.950 -  KdPrint((__DRIVER_NAME "     ndis_wrapper_handle = %p\n", ndis_wrapper_handle));
   4.951 -  if (!ndis_wrapper_handle)
   4.952 -  {
   4.953 -    KdPrint((__DRIVER_NAME "     NdisMInitializeWrapper failed\n"));
   4.954 -    return NDIS_STATUS_FAILURE;
   4.955 -  }
   4.956 -  KdPrint((__DRIVER_NAME "     NdisMInitializeWrapper succeeded\n"));
   4.957 -
   4.958 -  /* NDIS 5.1 driver */
   4.959 -  mini_chars.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION;
   4.960 -  mini_chars.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION;
   4.961 -
   4.962 -  KdPrint((__DRIVER_NAME "     MajorNdisVersion = %d,  MinorNdisVersion = %d\n", NDIS_MINIPORT_MAJOR_VERSION, NDIS_MINIPORT_MINOR_VERSION));
   4.963 -
   4.964 -  mini_chars.HaltHandler = XenNet_Halt;
   4.965 -  mini_chars.InitializeHandler = XenNet_Init;
   4.966 -  //mini_chars.ISRHandler = XenNet_InterruptIsr;
   4.967 -  //mini_chars.HandleInterruptHandler = XenNet_InterruptDpc;
   4.968 -  mini_chars.QueryInformationHandler = XenNet_QueryInformation;
   4.969 -  mini_chars.ResetHandler = XenNet_Reset;
   4.970 -  mini_chars.SetInformationHandler = XenNet_SetInformation;
   4.971 -  /* added in v.4 -- use multiple pkts interface */
   4.972 -  mini_chars.ReturnPacketHandler = XenNet_ReturnPacket;
   4.973 -  mini_chars.SendPacketsHandler = XenNet_SendPackets;
   4.974 -  /* don't support cancel - no point as packets are never queued for long */
   4.975 -  //mini_chars.CancelSendPacketsHandler = XenNet_CancelSendPackets;
   4.976 -
   4.977 -#ifdef NDIS51_MINIPORT
   4.978 -  /* added in v.5.1 */
   4.979 -  mini_chars.PnPEventNotifyHandler = XenNet_PnPEventNotify;
   4.980 -  mini_chars.AdapterShutdownHandler = XenNet_Shutdown;
   4.981 -#else
   4.982 -  // something else here
   4.983 -#endif
   4.984 -
   4.985 -  /* set up upper-edge interface */
   4.986 -  KdPrint((__DRIVER_NAME "     about to call NdisMRegisterMiniport\n"));
   4.987 -  status = NdisMRegisterMiniport(ndis_wrapper_handle, &mini_chars, sizeof(mini_chars));
   4.988 -  KdPrint((__DRIVER_NAME "     called NdisMRegisterMiniport\n"));
   4.989 -  if (!NT_SUCCESS(status))
   4.990 -  {
   4.991 -    KdPrint((__DRIVER_NAME "     NdisMRegisterMiniport failed, status = 0x%x\n", status));
   4.992 -    NdisTerminateWrapper(ndis_wrapper_handle, NULL);
   4.993 -    return status;
   4.994 -  }
   4.995 -
   4.996 -  FUNCTION_EXIT();
   4.997 -
   4.998 -  return status;
   4.999 -}
  4.1000 \ No newline at end of file
     5.1 --- a/xennet/xennet5.h	Sun Feb 10 23:12:03 2013 +1100
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,486 +0,0 @@
     5.4 -/*
     5.5 -PV Drivers for Windows Xen HVM Domains
     5.6 -Copyright (C) 2007 James Harper
     5.7 -Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
     5.8 -
     5.9 -This program is free software; you can redistribute it and/or
    5.10 -modify it under the terms of the GNU General Public License
    5.11 -as published by the Free Software Foundation; either version 2
    5.12 -of the License, or (at your option) any later version.
    5.13 -
    5.14 -This program is distributed in the hope that it will be useful,
    5.15 -but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.16 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.17 -GNU General Public License for more details.
    5.18 -
    5.19 -You should have received a copy of the GNU General Public License
    5.20 -along with this program; if not, write to the Free Software
    5.21 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    5.22 -*/
    5.23 -
    5.24 -#pragma warning(disable: 4201)
    5.25 -#pragma warning(disable: 4214)
    5.26 -
    5.27 -#include <ntddk.h>
    5.28 -#include <wdm.h>
    5.29 -#define NDIS_MINIPORT_DRIVER
    5.30 -#if NTDDI_VERSION < NTDDI_WINXP
    5.31 -# define NDIS50_MINIPORT 1
    5.32 -#else
    5.33 -# define NDIS51_MINIPORT 1
    5.34 -#endif
    5.35 -#include <ndis.h>
    5.36 -#define NTSTRSAFE_LIB
    5.37 -#include <ntstrsafe.h>
    5.38 -#include <liblfds.h>
    5.39 -
    5.40 -#define VENDOR_DRIVER_VERSION_MAJOR 0
    5.41 -#define VENDOR_DRIVER_VERSION_MINOR 10
    5.42 -
    5.43 -#define VENDOR_DRIVER_VERSION (((VENDOR_DRIVER_VERSION_MAJOR) << 16) | (VENDOR_DRIVER_VERSION_MINOR))
    5.44 -
    5.45 -#define __DRIVER_NAME "XenNet"
    5.46 -
    5.47 -#include <xen_windows.h>
    5.48 -#include <memory.h>
    5.49 -#include <grant_table.h>
    5.50 -#include <event_channel.h>
    5.51 -#include <hvm/params.h>
    5.52 -#include <hvm/hvm_op.h>
    5.53 -#include <xen_public.h>
    5.54 -#include <io/ring.h>
    5.55 -#include <io/netif.h>
    5.56 -#include <io/xenbus.h>
    5.57 -#include <stdlib.h>
    5.58 -#define XENNET_POOL_TAG (ULONG) 'XenN'
    5.59 -
    5.60 -/* Xen macros use these, so they need to be redefined to Win equivs */
    5.61 -#define wmb() KeMemoryBarrier()
    5.62 -#define mb() KeMemoryBarrier()
    5.63 -
    5.64 -#define GRANT_INVALID_REF 0
    5.65 -
    5.66 -#define NAME_SIZE 64
    5.67 -
    5.68 -#define ETH_ALEN 6
    5.69 -
    5.70 -/*
    5.71 -#define __NET_USHORT_BYTE_0(x) ((USHORT)(x & 0xFF))
    5.72 -#define __NET_USHORT_BYTE_1(x) ((USHORT)((PUCHAR)&x)[1] & 0xFF)
    5.73 -
    5.74 -#define GET_NET_USHORT(x) ((__NET_USHORT_BYTE_0(x) << 8) | __NET_USHORT_BYTE_1(x))
    5.75 -#define SET_NET_USHORT(y, x) *((USHORT *)&(y)) = ((__NET_USHORT_BYTE_0(x) << 8) | __NET_USHORT_BYTE_1(x))
    5.76 -*/
    5.77 -
    5.78 -static FORCEINLINE USHORT
    5.79 -GET_NET_USHORT(USHORT data)
    5.80 -{
    5.81 -  return (data << 8) | (data >> 8);
    5.82 -}
    5.83 -
    5.84 -static FORCEINLINE USHORT
    5.85 -GET_NET_PUSHORT(PVOID pdata)
    5.86 -{
    5.87 -  return (*((PUSHORT)pdata) << 8) | (*((PUSHORT)pdata) >> 8);
    5.88 -}
    5.89 -
    5.90 -static FORCEINLINE VOID
    5.91 -SET_NET_USHORT(PVOID ptr, USHORT data)
    5.92 -{
    5.93 -  *((PUSHORT)ptr) = GET_NET_USHORT(data);
    5.94 -}
    5.95 -
    5.96 -static FORCEINLINE ULONG
    5.97 -GET_NET_ULONG(ULONG data)
    5.98 -{
    5.99 -  ULONG tmp;
   5.100 -  
   5.101 -  tmp = ((data & 0x00ff00ff) << 8) | ((data & 0xff00ff00) >> 8);
   5.102 -  return (tmp << 16) | (tmp >> 16);
   5.103 -}
   5.104 -
   5.105 -static FORCEINLINE ULONG
   5.106 -GET_NET_PULONG(PVOID pdata)
   5.107 -{
   5.108 -  ULONG tmp;
   5.109 -  
   5.110 -  tmp = ((*((PULONG)pdata) & 0x00ff00ff) << 8) | ((*((PULONG)pdata) & 0xff00ff00) >> 8);
   5.111 -  return (tmp << 16) | (tmp >> 16);
   5.112 -}
   5.113 -
   5.114 -static FORCEINLINE VOID
   5.115 -SET_NET_ULONG(PVOID ptr, ULONG data)
   5.116 -{
   5.117 -  *((PULONG)ptr) = GET_NET_ULONG(data);
   5.118 -}
   5.119 -/*
   5.120 -#define GET_NET_ULONG(x) ((GET_NET_USHORT(x) << 16) | GET_NET_USHORT(((PUCHAR)&x)[2]))
   5.121 -#define SET_NET_ULONG(y, x) *((ULONG *)&(y)) = ((GET_NET_USHORT(x) << 16) | GET_NET_USHORT(((PUCHAR)&x)[2]))
   5.122 -*/
   5.123 -
   5.124 -#define SUPPORTED_PACKET_FILTERS (\
   5.125 -  NDIS_PACKET_TYPE_DIRECTED | \
   5.126 -  NDIS_PACKET_TYPE_MULTICAST | \
   5.127 -  NDIS_PACKET_TYPE_BROADCAST | \
   5.128 -  NDIS_PACKET_TYPE_PROMISCUOUS | \
   5.129 -  NDIS_PACKET_TYPE_ALL_MULTICAST)
   5.130 -
   5.131 -/* couldn't get regular xen ring macros to work...*/
   5.132 -#define __NET_RING_SIZE(type, _sz) \
   5.133 -    (__RD32( \
   5.134 -    (_sz - sizeof(struct type##_sring) + sizeof(union type##_sring_entry)) \
   5.135 -    / sizeof(union type##_sring_entry)))
   5.136 -
   5.137 -#define NET_TX_RING_SIZE __NET_RING_SIZE(netif_tx, PAGE_SIZE)
   5.138 -#define NET_RX_RING_SIZE __NET_RING_SIZE(netif_rx, PAGE_SIZE)
   5.139 -
   5.140 -#pragma warning(disable: 4127) // conditional expression is constant
   5.141 -
   5.142 -#define MIN_LARGE_SEND_SEGMENTS 4
   5.143 -
   5.144 -/* TODO: crank this up if we support higher mtus? */
   5.145 -#define XN_HDR_SIZE 14
   5.146 -#define XN_MAX_DATA_SIZE 1500
   5.147 -#define XN_MIN_FRAME_SIZE 60
   5.148 -#define XN_MAX_FRAME_SIZE (XN_HDR_SIZE + XN_DATA_SIZE)
   5.149 -/*
   5.150 -#if !defined(OFFLOAD_LARGE_SEND)
   5.151 -  #define XN_MAX_PKT_SIZE (XN_HDR_SIZE + XN_DATA_SIZE)
   5.152 -#else
   5.153 -  #define XN_MAX_PKT_SIZE MAX_LARGE_SEND_OFFLOAD
   5.154 -#endif
   5.155 -*/
   5.156 -
   5.157 -#define XN_MAX_SEND_PKTS 16
   5.158 -
   5.159 -#define XENSOURCE_MAC_HDR 0x00163E
   5.160 -#define XN_VENDOR_DESC "Xensource"
   5.161 -#define MAX_XENBUS_STR_LEN 128
   5.162 -
   5.163 -#define RX_MIN_TARGET 8
   5.164 -#define RX_DFL_MIN_TARGET 256
   5.165 -#define RX_MAX_TARGET min(NET_RX_RING_SIZE, 256)
   5.166 -
   5.167 -//#define MAX_BUFFERS_PER_PACKET NET_RX_RING_SIZE
   5.168 -
   5.169 -#define MIN_ETH_HEADER_LENGTH 14
   5.170 -#define MAX_ETH_HEADER_LENGTH 14
   5.171 -#define MIN_IP4_HEADER_LENGTH 20
   5.172 -#define MAX_IP4_HEADER_LENGTH (15 * 4)
   5.173 -#define MIN_TCP_HEADER_LENGTH 20
   5.174 -#define MAX_TCP_HEADER_LENGTH (15 * 4)
   5.175 -#define MAX_PKT_HEADER_LENGTH (MAX_ETH_HEADER_LENGTH + MAX_IP4_HEADER_LENGTH + MAX_TCP_HEADER_LENGTH)
   5.176 -
   5.177 -#define MIN_LOOKAHEAD_LENGTH (MAX_IP4_HEADER_LENGTH + MAX_TCP_HEADER_LENGTH)
   5.178 -#define MAX_LOOKAHEAD_LENGTH 256
   5.179 -
   5.180 -#define LINUX_MAX_SG_ELEMENTS 19
   5.181 -
   5.182 -struct _shared_buffer_t;
   5.183 -
   5.184 -typedef struct _shared_buffer_t shared_buffer_t;
   5.185 -
   5.186 -struct _shared_buffer_t
   5.187 -{
   5.188 -  struct netif_rx_response rsp;
   5.189 -  shared_buffer_t *next;
   5.190 -  grant_ref_t gref;
   5.191 -  USHORT offset;
   5.192 -  PVOID virtual;
   5.193 -  PNDIS_BUFFER buffer;
   5.194 -  volatile LONG ref_count;
   5.195 -};
   5.196 -
   5.197 -typedef struct
   5.198 -{
   5.199 -  PNDIS_PACKET packet; /* only set on the last packet */
   5.200 -  PVOID *cb;
   5.201 -  grant_ref_t gref;
   5.202 -} tx_shadow_t;
   5.203 -
   5.204 -typedef struct {
   5.205 -  PNDIS_BUFFER first_buffer;
   5.206 -  PNDIS_BUFFER curr_buffer;
   5.207 -  shared_buffer_t *first_pb;
   5.208 -  shared_buffer_t *curr_pb;
   5.209 -  PUCHAR first_buffer_virtual;
   5.210 -  ULONG mdl_count;
   5.211 -  ULONG curr_mdl_offset;
   5.212 -  USHORT mss;
   5.213 -  NDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
   5.214 -  BOOLEAN csum_blank;
   5.215 -  BOOLEAN data_validated;
   5.216 -  BOOLEAN split_required;
   5.217 -  UCHAR ip_version;
   5.218 -  PUCHAR header;
   5.219 -  ULONG first_buffer_length;
   5.220 -  ULONG header_length;
   5.221 -  UCHAR ip_proto;
   5.222 -  ULONG total_length;
   5.223 -  USHORT ip4_header_length;
   5.224 -  USHORT ip4_length;
   5.225 -  BOOLEAN ip_has_options;
   5.226 -  USHORT tcp_header_length;
   5.227 -  BOOLEAN tcp_has_options;
   5.228 -  USHORT tcp_length;
   5.229 -  USHORT tcp_remaining;
   5.230 -  ULONG tcp_seq;
   5.231 -  /* anything past here doesn't get cleared automatically by the ClearPacketInfo */
   5.232 -  UCHAR header_data[MAX_LOOKAHEAD_LENGTH + MAX_ETH_HEADER_LENGTH];
   5.233 -} packet_info_t;
   5.234 -
   5.235 -#define PAGE_LIST_SIZE (max(NET_RX_RING_SIZE, NET_TX_RING_SIZE) * 4)
   5.236 -#define MULTICAST_LIST_MAX_SIZE 32
   5.237 -
   5.238 -#define NDIS_STATUS_RESOURCES_MAX_LENGTH 64
   5.239 -
   5.240 -struct xennet_info
   5.241 -{
   5.242 -  BOOLEAN inactive;
   5.243 -  
   5.244 -  /* Base device vars */
   5.245 -  PDEVICE_OBJECT pdo;
   5.246 -  PDEVICE_OBJECT fdo;
   5.247 -  PDEVICE_OBJECT lower_do;
   5.248 -  //WDFDEVICE wdf_device;
   5.249 -  WCHAR dev_desc[NAME_SIZE];
   5.250 -
   5.251 -  /* NDIS-related vars */
   5.252 -  NDIS_HANDLE adapter_handle;
   5.253 -  NDIS_MINIPORT_INTERRUPT interrupt;
   5.254 -  ULONG packet_filter;
   5.255 -  BOOLEAN connected;
   5.256 -  BOOLEAN shutting_down;
   5.257 -  BOOLEAN tx_shutting_down;
   5.258 -  BOOLEAN rx_shutting_down;
   5.259 -  uint8_t perm_mac_addr[ETH_ALEN];
   5.260 -  uint8_t curr_mac_addr[ETH_ALEN];
   5.261 -  ULONG current_lookahead;
   5.262 -  NDIS_DEVICE_POWER_STATE new_power_state;
   5.263 -  NDIS_DEVICE_POWER_STATE power_state;
   5.264 -  PIO_WORKITEM power_workitem;
   5.265 -
   5.266 -  /* Misc. Xen vars */
   5.267 -  XENPCI_VECTORS vectors;
   5.268 -  PXENPCI_DEVICE_STATE device_state;
   5.269 -  evtchn_port_t event_channel;
   5.270 -  ULONG state;
   5.271 -  char backend_path[MAX_XENBUS_STR_LEN];
   5.272 -  ULONG backend_state;
   5.273 -  PVOID config_page;
   5.274 -  UCHAR multicast_list[MULTICAST_LIST_MAX_SIZE][6];
   5.275 -  ULONG multicast_list_size;
   5.276 -  KDPC suspend_dpc;
   5.277 -  PIO_WORKITEM resume_work_item;
   5.278 -  KSPIN_LOCK resume_lock;
   5.279 -  KDPC rxtx_dpc;
   5.280 -
   5.281 -  /* tx related - protected by tx_lock */
   5.282 -  KSPIN_LOCK tx_lock;
   5.283 -  LIST_ENTRY tx_waiting_pkt_list;
   5.284 -  struct netif_tx_front_ring tx;
   5.285 -  ULONG tx_ring_free;
   5.286 -  tx_shadow_t tx_shadows[NET_TX_RING_SIZE];
   5.287 -  NDIS_HANDLE tx_buffer_pool;
   5.288 -#define TX_HEADER_BUFFER_SIZE 512
   5.289 -//#define TX_COALESCE_BUFFERS (NET_TX_RING_SIZE >> 2)
   5.290 -#define TX_COALESCE_BUFFERS (NET_TX_RING_SIZE)
   5.291 -  KEVENT tx_idle_event;
   5.292 -  ULONG tx_outstanding;
   5.293 -  ULONG tx_id_free;
   5.294 -  USHORT tx_id_list[NET_TX_RING_SIZE];
   5.295 -  NPAGED_LOOKASIDE_LIST tx_lookaside_list;
   5.296 -
   5.297 -  /* rx_related - protected by rx_lock */
   5.298 -  KSPIN_LOCK rx_lock;
   5.299 -  struct netif_rx_front_ring rx;
   5.300 -  ULONG rx_id_free;
   5.301 -  packet_info_t *rxpi;
   5.302 -  KEVENT packet_returned_event;
   5.303 -  //NDIS_MINIPORT_TIMER rx_timer;
   5.304 -  KTIMER rx_timer;
   5.305 -  KDPC rx_timer_dpc;
   5.306 -  NDIS_HANDLE rx_packet_pool;
   5.307 -  NDIS_HANDLE rx_buffer_pool;
   5.308 -  volatile LONG rx_pb_free;
   5.309 -  struct stack_state *rx_packet_stack;
   5.310 -  struct stack_state *rx_pb_stack;
   5.311 -  shared_buffer_t *rx_ring_pbs[NET_RX_RING_SIZE];
   5.312 -  NPAGED_LOOKASIDE_LIST rx_lookaside_list;
   5.313 -  /* Receive-ring batched refills. */
   5.314 -  ULONG rx_target;
   5.315 -  ULONG rx_max_target;
   5.316 -  ULONG rx_min_target;
   5.317 -  shared_buffer_t *rx_partial_buf;
   5.318 -  BOOLEAN rx_partial_extra_info_flag ;
   5.319 -  BOOLEAN rx_partial_more_data_flag;
   5.320 -
   5.321 -  /* how many packets are in the net stack atm */
   5.322 -  LONG rx_outstanding;
   5.323 -
   5.324 -  /* config vars from registry */
   5.325 -  ULONG config_sg;
   5.326 -  ULONG config_csum;
   5.327 -  ULONG config_csum_rx_check;
   5.328 -  ULONG config_csum_rx_dont_fix;
   5.329 -  ULONG config_gso;
   5.330 -  ULONG config_mtu;
   5.331 -  ULONG config_rx_interrupt_moderation;
   5.332 -
   5.333 -  NDIS_TASK_TCP_IP_CHECKSUM setting_csum;
   5.334 -  ULONG setting_max_offload;
   5.335 -
   5.336 -  /* config stuff calculated from the above */
   5.337 -  ULONG config_max_pkt_size;
   5.338 -
   5.339 -  /* stats */
   5.340 -  ULONG64 stat_tx_ok;
   5.341 -  ULONG64 stat_rx_ok;
   5.342 -  ULONG64 stat_tx_error;
   5.343 -  ULONG64 stat_rx_error;
   5.344 -  ULONG64 stat_rx_no_buffer;
   5.345 -  
   5.346 -} typedef xennet_info_t;
   5.347 -
   5.348 -VOID
   5.349 -XenNet_ReturnPacket(
   5.350 -  IN NDIS_HANDLE MiniportAdapterContext,
   5.351 -  IN PNDIS_PACKET Packet
   5.352 -  );
   5.353 -
   5.354 -BOOLEAN
   5.355 -XenNet_RxInit(xennet_info_t *xi);
   5.356 -
   5.357 -BOOLEAN
   5.358 -XenNet_RxShutdown(xennet_info_t *xi);
   5.359 -
   5.360 -VOID
   5.361 -XenNet_RxResumeStart(xennet_info_t *xi);
   5.362 -
   5.363 -VOID
   5.364 -XenNet_RxResumeEnd(xennet_info_t *xi);
   5.365 -
   5.366 -BOOLEAN
   5.367 -XenNet_RxBufferCheck(struct xennet_info *xi);
   5.368 -
   5.369 -VOID
   5.370 -XenNet_TxResumeStart(xennet_info_t *xi);
   5.371 -
   5.372 -VOID
   5.373 -XenNet_TxResumeEnd(xennet_info_t *xi);
   5.374 -
   5.375 -VOID
   5.376 -XenNet_SendPackets(
   5.377 -  IN NDIS_HANDLE MiniportAdapterContext,
   5.378 -  IN PPNDIS_PACKET PacketArray,
   5.379 -  IN UINT NumberOfPackets
   5.380 -  );
   5.381 -
   5.382 -VOID
   5.383 -XenNet_CancelSendPackets(
   5.384 -  NDIS_HANDLE MiniportAdapterContext,
   5.385 -  PVOID CancelId);
   5.386 -  
   5.387 -BOOLEAN
   5.388 -XenNet_TxInit(xennet_info_t *xi);
   5.389 -
   5.390 -BOOLEAN
   5.391 -XenNet_TxShutdown(xennet_info_t *xi);
   5.392 -
   5.393 -VOID
   5.394 -XenNet_TxBufferGC(struct xennet_info *xi, BOOLEAN dont_set_event);
   5.395 -
   5.396 -NDIS_STATUS
   5.397 -XenNet_QueryInformation(
   5.398 -  IN NDIS_HANDLE MiniportAdapterContext,
   5.399 -  IN NDIS_OID Oid,
   5.400 -  IN PVOID InformationBuffer,
   5.401 -  IN ULONG InformationBufferLength,
   5.402 -  OUT PULONG BytesWritten,
   5.403 -  OUT PULONG BytesNeeded);
   5.404 -
   5.405 -NDIS_STATUS
   5.406 -XenNet_SetInformation(
   5.407 -  IN NDIS_HANDLE MiniportAdapterContext,
   5.408 -  IN NDIS_OID Oid,
   5.409 -  IN PVOID InformationBuffer,
   5.410 -  IN ULONG InformationBufferLength,
   5.411 -  OUT PULONG BytesRead,
   5.412 -  OUT PULONG BytesNeeded
   5.413 -  );
   5.414 -
   5.415 -NDIS_STATUS
   5.416 -XenNet_D0Entry(struct xennet_info *xi);
   5.417 -NDIS_STATUS
   5.418 -XenNet_D0Exit(struct xennet_info *xi);
   5.419 -IO_WORKITEM_ROUTINE
   5.420 -XenNet_SetPower;
   5.421 -
   5.422 -/* return values */
   5.423 -#define PARSE_OK 0
   5.424 -#define PARSE_TOO_SMALL 1 /* first buffer is too small */
   5.425 -#define PARSE_UNKNOWN_TYPE 2
   5.426 -
   5.427 -BOOLEAN
   5.428 -XenNet_BuildHeader(packet_info_t *pi, PVOID header, ULONG new_header_size);
   5.429 -ULONG
   5.430 -XenNet_ParsePacketHeader(packet_info_t *pi, PUCHAR buffer, ULONG min_header_size);
   5.431 -BOOLEAN
   5.432 -XenNet_FilterAcceptPacket(struct xennet_info *xi,packet_info_t *pi);
   5.433 -
   5.434 -VOID
   5.435 -XenNet_SumIpHeader(
   5.436 -  PUCHAR header,
   5.437 -  USHORT ip4_header_length
   5.438 -);
   5.439 -
   5.440 -BOOLEAN
   5.441 -XenNet_CheckIpHeader(
   5.442 -  PUCHAR header,
   5.443 -  USHORT ip4_header_length
   5.444 -);
   5.445 -
   5.446 -static __forceinline VOID
   5.447 -XenNet_ClearPacketInfo(packet_info_t *pi)
   5.448 -{
   5.449 -#if 1
   5.450 -  RtlZeroMemory(pi, sizeof(packet_info_t) - FIELD_OFFSET(packet_info_t, header_data));
   5.451 -#else
   5.452 -  pi->mdl_count = 0;
   5.453 -  pi->mss = 0;
   5.454 -  pi->ip4_header_length = 0;
   5.455 -  pi->tcp_header_length = 0;
   5.456 -  pi->curr_mdl_index = pi->curr_mdl_offset = 0;
   5.457 -  pi->extra_info = pi->more_frags = pi->csum_blank =
   5.458 -    pi->data_validated = pi->split_required = 0;
   5.459 -#endif
   5.460 -}
   5.461 -
   5.462 -/* Get some data from the current packet, but don't cross a page boundry. */
   5.463 -static __forceinline ULONG
   5.464 -XenNet_QueryData(packet_info_t *pi, ULONG length)
   5.465 -{
   5.466 -  ULONG offset_in_page;
   5.467 -  
   5.468 -  if (length > MmGetMdlByteCount(pi->curr_buffer) - pi->curr_mdl_offset)
   5.469 -    length = MmGetMdlByteCount(pi->curr_buffer) - pi->curr_mdl_offset;
   5.470 -
   5.471 -  offset_in_page = (MmGetMdlByteOffset(pi->curr_buffer) + pi->curr_mdl_offset) & (PAGE_SIZE - 1);
   5.472 -  if (offset_in_page + length > PAGE_SIZE)
   5.473 -    length = PAGE_SIZE - offset_in_page;
   5.474 -  
   5.475 -  return length;
   5.476 -}
   5.477 -
   5.478 -/* Move the pointers forward by the given amount. No error checking is done.  */
   5.479 -static __forceinline VOID
   5.480 -XenNet_EatData(packet_info_t *pi, ULONG length)
   5.481 -{
   5.482 -  pi->curr_mdl_offset += length;
   5.483 -  if (pi->curr_mdl_offset >= MmGetMdlByteCount(pi->curr_buffer))
   5.484 -  {
   5.485 -    pi->curr_mdl_offset -= MmGetMdlByteCount(pi->curr_buffer);
   5.486 -    NdisGetNextBuffer(pi->curr_buffer, &pi->curr_buffer);
   5.487 -  }
   5.488 -}
   5.489 -
     6.1 --- a/xennet/xennet5_common.c	Sun Feb 10 23:12:03 2013 +1100
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,308 +0,0 @@
     6.4 -/*
     6.5 -PV Net Driver for Windows Xen HVM Domains
     6.6 -Copyright (C) 2007 James Harper
     6.7 -Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
     6.8 -
     6.9 -This program is free software; you can redistribute it and/or
    6.10 -modify it under the terms of the GNU General Public License
    6.11 -as published by the Free Software Foundation; either version 2
    6.12 -of the License, or (at your option) any later version.
    6.13 -
    6.14 -This program is distributed in the hope that it will be useful,
    6.15 -but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.16 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.17 -GNU General Public License for more details.
    6.18 -
    6.19 -You should have received a copy of the GNU General Public License
    6.20 -along with this program; if not, write to the Free Software
    6.21 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    6.22 -*/
    6.23 -
    6.24 -#include "xennet5.h"
    6.25 -
    6.26 -/* Increase the header to a certain size */
    6.27 -BOOLEAN
    6.28 -XenNet_BuildHeader(packet_info_t *pi, PUCHAR header, ULONG new_header_size)
    6.29 -{
    6.30 -  ULONG bytes_remaining;
    6.31 -
    6.32 -  //FUNCTION_ENTER();
    6.33 -
    6.34 -  if (!header)
    6.35 -    header = pi->header;
    6.36 -
    6.37 -  if (new_header_size <= pi->header_length)
    6.38 -  {
    6.39 -    return TRUE; /* header is already at least the required size */
    6.40 -  }
    6.41 -
    6.42 -  if (header == pi->first_buffer_virtual)
    6.43 -  {
    6.44 -    /* still working in the first buffer */
    6.45 -    if (new_header_size <= pi->first_buffer_length)
    6.46 -    {
    6.47 -      //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " new_header_size <= pi->first_buffer_length\n"));
    6.48 -      pi->header_length = new_header_size;
    6.49 -      if (pi->header_length == pi->first_buffer_length)
    6.50 -      {
    6.51 -        NdisGetNextBuffer(pi->curr_buffer, &pi->curr_buffer);
    6.52 -        pi->curr_mdl_offset = 0;
    6.53 -        if (pi->curr_pb)
    6.54 -          pi->curr_pb = pi->curr_pb->next;
    6.55 -      }
    6.56 -      else
    6.57 -      {
    6.58 -        pi->curr_mdl_offset = (USHORT)new_header_size;
    6.59 -      }      
    6.60 -      return TRUE;
    6.61 -    }
    6.62 -    else
    6.63 -    {
    6.64 -      //KdPrint((__DRIVER_NAME "     Switching to header_data\n"));
    6.65 -      memcpy(pi->header_data, header, pi->header_length);
    6.66 -      header = pi->header = pi->header_data;
    6.67 -    }
    6.68 -  }
    6.69 -  
    6.70 -  bytes_remaining = new_header_size - pi->header_length;
    6.71 -  // TODO: if there are only a small number of bytes left in the current buffer then increase to consume that too... it would have to be no more than the size of header+mss though
    6.72 -
    6.73 -  //KdPrint((__DRIVER_NAME "     A bytes_remaining = %d, pi->curr_buffer = %p, pi->mdl_count = %d\n", bytes_remaining, pi->curr_buffer, pi->mdl_count));
    6.74 -  while (bytes_remaining && pi->curr_buffer)
    6.75 -  {
    6.76 -    ULONG copy_size;
    6.77 -    
    6.78 -    ASSERT(pi->curr_buffer);
    6.79 -    //KdPrint((__DRIVER_NAME "     B bytes_remaining = %d, pi->curr_buffer = %p, pi->mdl_count = %d\n", bytes_remaining, pi->curr_buffer, pi->mdl_count));
    6.80 -    if (MmGetMdlByteCount(pi->curr_buffer))
    6.81 -    {
    6.82 -      PUCHAR src_addr;
    6.83 -      src_addr = MmGetSystemAddressForMdlSafe(pi->curr_buffer, NormalPagePriority);
    6.84 -      if (!src_addr)
    6.85 -        return FALSE;
    6.86 -      copy_size = min(bytes_remaining, MmGetMdlByteCount(pi->curr_buffer) - pi->curr_mdl_offset);
    6.87 -      //KdPrint((__DRIVER_NAME "     B copy_size = %d\n", copy_size));
    6.88 -      memcpy(header + pi->header_length,
    6.89 -        src_addr + pi->curr_mdl_offset, copy_size);
    6.90 -      pi->curr_mdl_offset = (USHORT)(pi->curr_mdl_offset + copy_size);
    6.91 -      pi->header_length += copy_size;
    6.92 -      bytes_remaining -= copy_size;
    6.93 -    }
    6.94 -    if (pi->curr_mdl_offset == MmGetMdlByteCount(pi->curr_buffer))
    6.95 -    {
    6.96 -      NdisGetNextBuffer(pi->curr_buffer, &pi->curr_buffer);
    6.97 -      if (pi->curr_pb)
    6.98 -        pi->curr_pb = pi->curr_pb->next;
    6.99 -      pi->curr_mdl_offset = 0;
   6.100 -    }
   6.101 -  }
   6.102 -  //KdPrint((__DRIVER_NAME "     C bytes_remaining = %d, pi->curr_buffer = %p, pi->mdl_count = %d\n", bytes_remaining, pi->curr_buffer, pi->mdl_count));
   6.103 -  if (bytes_remaining)
   6.104 -  {
   6.105 -    //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " bytes_remaining\n"));
   6.106 -    return FALSE;
   6.107 -  }
   6.108 -  //FUNCTION_EXIT();
   6.109 -  return TRUE;
   6.110 -}
   6.111 -
   6.112 -ULONG
   6.113 -XenNet_ParsePacketHeader(packet_info_t *pi, PUCHAR alt_buffer, ULONG min_header_size)
   6.114 -{
   6.115 -  //FUNCTION_ENTER();
   6.116 -
   6.117 -  ASSERT(pi->first_buffer);
   6.118 -  
   6.119 -  NdisQueryBufferSafe(pi->first_buffer, (PVOID)&pi->first_buffer_virtual, &pi->first_buffer_length, NormalPagePriority);
   6.120 -  pi->curr_buffer = pi->first_buffer;
   6.121 -  if (alt_buffer)
   6.122 -    pi->header = alt_buffer;
   6.123 -  else
   6.124 -    pi->header = pi->first_buffer_virtual;
   6.125 -
   6.126 -  pi->header_length = 0;
   6.127 -  pi->curr_mdl_offset = 0;
   6.128 -
   6.129 -  XenNet_BuildHeader(pi, NULL, min_header_size);
   6.130 -  
   6.131 -  if (!XenNet_BuildHeader(pi, NULL, (ULONG)XN_HDR_SIZE))
   6.132 -  {
   6.133 -    KdPrint((__DRIVER_NAME "     packet too small (Ethernet Header)\n"));
   6.134 -    return PARSE_TOO_SMALL;
   6.135 -  }
   6.136 -
   6.137 -  switch (GET_NET_PUSHORT(&pi->header[12])) // L2 protocol field
   6.138 -  {
   6.139 -  case 0x0800:
   6.140 -    //KdPrint((__DRIVER_NAME "     IP\n"));
   6.141 -    if (pi->header_length < (ULONG)(XN_HDR_SIZE + 20))
   6.142 -    {
   6.143 -      if (!XenNet_BuildHeader(pi, NULL, (ULONG)(XN_HDR_SIZE + 20)))
   6.144 -      {
   6.145 -        KdPrint((__DRIVER_NAME "     packet too small (IP Header)\n"));
   6.146 -        return PARSE_TOO_SMALL;
   6.147 -      }
   6.148 -    }
   6.149 -    pi->ip_version = (pi->header[XN_HDR_SIZE + 0] & 0xF0) >> 4;
   6.150 -    if (pi->ip_version != 4)
   6.151 -    {
   6.152 -      KdPrint((__DRIVER_NAME "     ip_version = %d\n", pi->ip_version));
   6.153 -      return PARSE_UNKNOWN_TYPE;
   6.154 -    }
   6.155 -    pi->ip4_header_length = (pi->header[XN_HDR_SIZE + 0] & 0x0F) << 2;
   6.156 -    pi->ip_has_options = (BOOLEAN)(pi->ip4_header_length > 20);
   6.157 -    if (pi->header_length < (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20))
   6.158 -    {
   6.159 -      if (!XenNet_BuildHeader(pi, NULL, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20)))
   6.160 -      {
   6.161 -        //KdPrint((__DRIVER_NAME "     packet too small (IP Header + IP Options + TCP Header)\n"));
   6.162 -        return PARSE_TOO_SMALL;
   6.163 -      }
   6.164 -    }
   6.165 -    break;
   6.166 -  default:
   6.167 -    //KdPrint((__DRIVER_NAME "     Not IP (%d)\n", GET_NET_PUSHORT(&pi->header[12])));
   6.168 -    return PARSE_UNKNOWN_TYPE;
   6.169 -  }
   6.170 -  pi->ip_proto = pi->header[XN_HDR_SIZE + 9];
   6.171 -  switch (pi->ip_proto)
   6.172 -  {
   6.173 -  case 6:  // TCP
   6.174 -  case 17: // UDP
   6.175 -    break;
   6.176 -  default:
   6.177 -    //KdPrint((__DRIVER_NAME "     Not TCP/UDP (%d)\n", pi->ip_proto));
   6.178 -    return PARSE_UNKNOWN_TYPE;
   6.179 -  }
   6.180 -  pi->ip4_length = GET_NET_PUSHORT(&pi->header[XN_HDR_SIZE + 2]);
   6.181 -  pi->tcp_header_length = (pi->header[XN_HDR_SIZE + pi->ip4_header_length + 12] & 0xf0) >> 2;
   6.182 -
   6.183 -  if (pi->header_length < (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + pi->tcp_header_length))
   6.184 -  {
   6.185 -    if (!XenNet_BuildHeader(pi, NULL, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + pi->tcp_header_length)))
   6.186 -    {
   6.187 -      //KdPrint((__DRIVER_NAME "     packet too small (IP Header + IP Options + TCP Header + TCP Options)\n"));
   6.188 -      return PARSE_TOO_SMALL;
   6.189 -    }
   6.190 -  }
   6.191 -  
   6.192 -  if ((ULONG)XN_HDR_SIZE + pi->ip4_length > pi->total_length)
   6.193 -  {
   6.194 -    KdPrint((__DRIVER_NAME "     XN_HDR_SIZE + ip4_length (%d) > total_length (%d)\n", XN_HDR_SIZE + pi->ip4_length, pi->total_length));
   6.195 -    return PARSE_UNKNOWN_TYPE;
   6.196 -  }
   6.197 -
   6.198 -  pi->tcp_length = pi->ip4_length - pi->ip4_header_length - pi->tcp_header_length;
   6.199 -  pi->tcp_remaining = pi->tcp_length;
   6.200 -  pi->tcp_seq = GET_NET_PULONG(&pi->header[XN_HDR_SIZE + pi->ip4_header_length + 4]);
   6.201 -  pi->tcp_has_options = (BOOLEAN)(pi->tcp_header_length > 20);
   6.202 -  if (pi->mss > 0 && pi->tcp_length > pi->mss)
   6.203 -    pi->split_required = TRUE;
   6.204 -
   6.205 -  //KdPrint((__DRIVER_NAME "     ip4_length = %d\n", pi->ip4_length));
   6.206 -  //KdPrint((__DRIVER_NAME "     tcp_length = %d\n", pi->tcp_length));
   6.207 -  //FUNCTION_EXIT();
   6.208 -  
   6.209 -  return PARSE_OK;
   6.210 -}
   6.211 -
   6.212 -VOID
   6.213 -XenNet_SumIpHeader(
   6.214 -  PUCHAR header,
   6.215 -  USHORT ip4_header_length
   6.216 -)
   6.217 -{
   6.218 -  ULONG csum = 0;
   6.219 -  USHORT i;
   6.220 -
   6.221 -  ASSERT(ip4_header_length > 12);
   6.222 -  ASSERT(!(ip4_header_length & 1));
   6.223 -
   6.224 -  header[XN_HDR_SIZE + 10] = 0;
   6.225 -  header[XN_HDR_SIZE + 11] = 0;
   6.226 -  for (i = 0; i < ip4_header_length; i += 2)
   6.227 -  {
   6.228 -    csum += GET_NET_PUSHORT(&header[XN_HDR_SIZE + i]);
   6.229 -  }
   6.230 -  while (csum & 0xFFFF0000)
   6.231 -    csum = (csum & 0xFFFF) + (csum >> 16);
   6.232 -  csum = ~csum;
   6.233 -  SET_NET_USHORT(&header[XN_HDR_SIZE + 10], (USHORT)csum);
   6.234 -}
   6.235 -
   6.236 -BOOLEAN
   6.237 -XenNet_CheckIpHeader(
   6.238 -  PUCHAR header,
   6.239 -  USHORT ip4_header_length
   6.240 -)
   6.241 -{
   6.242 -  ULONG csum = 0;
   6.243 -  USHORT i;
   6.244 -
   6.245 -  ASSERT(ip4_header_length > 12);
   6.246 -  ASSERT(!(ip4_header_length & 1));
   6.247 -
   6.248 -  for (i = 0; i < ip4_header_length; i += 2)
   6.249 -  {
   6.250 -    csum += GET_NET_PUSHORT(&header[XN_HDR_SIZE + i]);
   6.251 -  }
   6.252 -  while (csum & 0xFFFF0000)
   6.253 -    csum = (csum & 0xFFFF) + (csum >> 16);
   6.254 -  return (BOOLEAN)(csum == 0xFFFF);
   6.255 -}
   6.256 -
   6.257 -BOOLEAN
   6.258 -XenNet_FilterAcceptPacket(struct xennet_info *xi,packet_info_t *pi)
   6.259 -{
   6.260 -  BOOLEAN is_multicast = FALSE;
   6.261 -  BOOLEAN is_my_multicast = FALSE;
   6.262 -  BOOLEAN is_broadcast = FALSE;
   6.263 -  BOOLEAN is_directed = FALSE;
   6.264 -  ULONG i;
   6.265 -
   6.266 -  if (pi->header[0] == 0xFF && pi->header[1] == 0xFF
   6.267 -      && pi->header[2] == 0xFF && pi->header[3] == 0xFF
   6.268 -      && pi->header[4] == 0xFF && pi->header[5] == 0xFF)
   6.269 -  {
   6.270 -    is_broadcast = TRUE;
   6.271 -  }
   6.272 -  else if (pi->header[0] & 0x01)
   6.273 -  {
   6.274 -    is_multicast = TRUE;
   6.275 -    for (i = 0; i < xi->multicast_list_size; i++)
   6.276 -    {
   6.277 -      if (memcmp(xi->multicast_list[i], pi->header, 6) == 0)
   6.278 -        break;
   6.279 -    }
   6.280 -    if (i < xi->multicast_list_size)
   6.281 -    {
   6.282 -      is_my_multicast = TRUE;
   6.283 -    }    
   6.284 -  }
   6.285 -  if (memcmp(xi->curr_mac_addr, pi->header, ETH_ALEN) == 0)
   6.286 -  {
   6.287 -    is_directed = TRUE;
   6.288 -  }
   6.289 -
   6.290 -  if (is_directed && (xi->packet_filter & NDIS_PACKET_TYPE_DIRECTED))
   6.291 -  {
   6.292 -    return TRUE;
   6.293 -  }  
   6.294 -  if (is_my_multicast && (xi->packet_filter & NDIS_PACKET_TYPE_MULTICAST))
   6.295 -  {
   6.296 -    return TRUE;
   6.297 -  }
   6.298 -  if (is_multicast && (xi->packet_filter & NDIS_PACKET_TYPE_ALL_MULTICAST))
   6.299 -  {
   6.300 -    return TRUE;
   6.301 -  }
   6.302 -  if (is_broadcast && (xi->packet_filter & NDIS_PACKET_TYPE_BROADCAST))
   6.303 -  {
   6.304 -    return TRUE;
   6.305 -  }
   6.306 -  if (xi->packet_filter & NDIS_PACKET_TYPE_PROMISCUOUS)
   6.307 -  {
   6.308 -    return TRUE;
   6.309 -  }
   6.310 -  return FALSE;
   6.311 -}
     7.1 --- a/xennet/xennet5_oid.c	Sun Feb 10 23:12:03 2013 +1100
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,772 +0,0 @@
     7.4 -/*
     7.5 -PV Net Driver for Windows Xen HVM Domains
     7.6 -Copyright (C) 2007 James Harper
     7.7 -Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
     7.8 -
     7.9 -This program is free software; you can redistribute it and/or
    7.10 -modify it under the terms of the GNU General Public License
    7.11 -as published by the Free Software Foundation; either version 2
    7.12 -of the License, or (at your option) any later version.
    7.13 -
    7.14 -This program is distributed in the hope that it will be useful,
    7.15 -but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.16 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.17 -GNU General Public License for more details.
    7.18 -
    7.19 -You should have received a copy of the GNU General Public License
    7.20 -along with this program; if not, write to the Free Software
    7.21 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    7.22 -*/
    7.23 -
    7.24 -#include "xennet5.h"
    7.25 -
    7.26 -// Q = Query Mandatory, S = Set Mandatory
    7.27 -NDIS_OID supported_oids[] =
    7.28 -{
    7.29 -  /* general OIDs */
    7.30 -  OID_GEN_SUPPORTED_LIST,        // Q
    7.31 -  OID_GEN_HARDWARE_STATUS,       // Q
    7.32 -  OID_GEN_MEDIA_SUPPORTED,       // Q
    7.33 -  OID_GEN_MEDIA_IN_USE,          // Q
    7.34 -  OID_GEN_MAXIMUM_LOOKAHEAD,     // Q
    7.35 -  OID_GEN_MAXIMUM_FRAME_SIZE,    // Q
    7.36 -  OID_GEN_LINK_SPEED,            // Q
    7.37 -  OID_GEN_TRANSMIT_BUFFER_SPACE, // Q
    7.38 -  OID_GEN_RECEIVE_BUFFER_SPACE,  // Q
    7.39 -  OID_GEN_TRANSMIT_BLOCK_SIZE,   // Q
    7.40 -  OID_GEN_RECEIVE_BLOCK_SIZE,    // Q
    7.41 -  OID_GEN_VENDOR_ID,             // Q
    7.42 -  OID_GEN_VENDOR_DESCRIPTION,    // Q
    7.43 -  OID_GEN_CURRENT_PACKET_FILTER, // QS
    7.44 -  OID_GEN_CURRENT_LOOKAHEAD,     // QS
    7.45 -  OID_GEN_DRIVER_VERSION,        // Q
    7.46 -  OID_GEN_VENDOR_DRIVER_VERSION, // Q
    7.47 -  OID_GEN_MAXIMUM_TOTAL_SIZE,    // Q
    7.48 -  OID_GEN_PROTOCOL_OPTIONS,      // S
    7.49 -  OID_GEN_MAC_OPTIONS,           // Q
    7.50 -  OID_GEN_MEDIA_CONNECT_STATUS,  // Q
    7.51 -  OID_GEN_MAXIMUM_SEND_PACKETS,  // Q
    7.52 -  /* stats */
    7.53 -  OID_GEN_XMIT_OK,               // Q
    7.54 -  OID_GEN_RCV_OK,                // Q
    7.55 -  OID_GEN_XMIT_ERROR,            // Q
    7.56 -  OID_GEN_RCV_ERROR,             // Q
    7.57 -  OID_GEN_RCV_NO_BUFFER,         // Q
    7.58 -  /* media-specific OIDs */
    7.59 -  OID_802_3_PERMANENT_ADDRESS,
    7.60 -  OID_802_3_CURRENT_ADDRESS,
    7.61 -  OID_802_3_MULTICAST_LIST,
    7.62 -  OID_802_3_MAXIMUM_LIST_SIZE,
    7.63 -  OID_802_3_RCV_ERROR_ALIGNMENT,
    7.64 -  OID_802_3_XMIT_ONE_COLLISION,
    7.65 -  OID_802_3_XMIT_MORE_COLLISIONS,
    7.66 -  /* tcp offload */
    7.67 -  OID_TCP_TASK_OFFLOAD,
    7.68 -  /* power */
    7.69 -  OID_PNP_CAPABILITIES,
    7.70 -  OID_PNP_SET_POWER,
    7.71 -  OID_PNP_QUERY_POWER,
    7.72 -};
    7.73 -
    7.74 -/* return 4 or 8 depending on size of buffer */
    7.75 -#define HANDLE_STAT_RETURN \
    7.76 -  {if (InformationBufferLength == 4) { \
    7.77 -    len = 4; *BytesNeeded = 8; \
    7.78 -    } else { \
    7.79 -    len = 8; \
    7.80 -    } }
    7.81 -
    7.82 -NDIS_STATUS
    7.83 -XenNet_QueryInformation(
    7.84 -  IN NDIS_HANDLE MiniportAdapterContext,
    7.85 -  IN NDIS_OID Oid,
    7.86 -  IN PVOID InformationBuffer,
    7.87 -  IN ULONG InformationBufferLength,
    7.88 -  OUT PULONG BytesWritten,
    7.89 -  OUT PULONG BytesNeeded)
    7.90 -{
    7.91 -  struct xennet_info *xi = MiniportAdapterContext;
    7.92 -  UCHAR vendor_desc[] = XN_VENDOR_DESC;
    7.93 -  ULONG64 temp_data;
    7.94 -  PVOID data = &temp_data;
    7.95 -  UINT len = 4;
    7.96 -  BOOLEAN used_temp_buffer = TRUE;
    7.97 -  NDIS_STATUS status = NDIS_STATUS_SUCCESS;
    7.98 -  PNDIS_TASK_OFFLOAD_HEADER ntoh;
    7.99 -  PNDIS_TASK_OFFLOAD nto;
   7.100 -  PNDIS_TASK_TCP_IP_CHECKSUM nttic;
   7.101 -  PNDIS_TASK_TCP_LARGE_SEND nttls;
   7.102 -  PNDIS_PNP_CAPABILITIES npc;
   7.103 -
   7.104 -  *BytesNeeded = 0;
   7.105 -  *BytesWritten = 0;
   7.106 -
   7.107 -// FUNCTION_ENTER()
   7.108 -
   7.109 -  switch(Oid)
   7.110 -  {
   7.111 -    case OID_GEN_SUPPORTED_LIST:
   7.112 -      data = supported_oids;
   7.113 -      len = sizeof(supported_oids);
   7.114 -      break;
   7.115 -    case OID_GEN_HARDWARE_STATUS:
   7.116 -      if (!xi->connected)
   7.117 -      {
   7.118 -        temp_data = NdisHardwareStatusInitializing;
   7.119 -        FUNCTION_MSG("NdisHardwareStatusInitializing\n");
   7.120 -      }
   7.121 -      else
   7.122 -      {
   7.123 -        temp_data = NdisHardwareStatusReady;
   7.124 -        FUNCTION_MSG("NdisHardwareStatusReady\n");
   7.125 -      }
   7.126 -      break;
   7.127 -    case OID_GEN_MEDIA_SUPPORTED:
   7.128 -      temp_data = NdisMedium802_3;
   7.129 -      break;
   7.130 -    case OID_GEN_MEDIA_IN_USE:
   7.131 -      temp_data = NdisMedium802_3;
   7.132 -      break;
   7.133 -    case OID_GEN_MAXIMUM_LOOKAHEAD:
   7.134 -      temp_data = MAX_LOOKAHEAD_LENGTH; //xi->config_mtu;
   7.135 -      break;
   7.136 -    case OID_GEN_MAXIMUM_FRAME_SIZE:
   7.137 -      temp_data = xi->config_mtu;
   7.138 -      break;
   7.139 -    case OID_GEN_LINK_SPEED:
   7.140 -      temp_data = 10000000; /* 1Gb */
   7.141 -      break;
   7.142 -    case OID_GEN_TRANSMIT_BUFFER_SPACE:
   7.143 -      /* multiply this by some small number as we can queue additional packets */
   7.144 -      temp_data = PAGE_SIZE * NET_TX_RING_SIZE * 4;
   7.145 -      break;
   7.146 -    case OID_GEN_RECEIVE_BUFFER_SPACE:
   7.147 -      temp_data = PAGE_SIZE * NET_RX_RING_SIZE * 2;
   7.148 -      break;
   7.149 -    case OID_GEN_TRANSMIT_BLOCK_SIZE:
   7.150 -      temp_data = PAGE_SIZE; //XN_MAX_PKT_SIZE;
   7.151 -      break;
   7.152 -    case OID_GEN_RECEIVE_BLOCK_SIZE:
   7.153 -      temp_data = PAGE_SIZE; //XN_MAX_PKT_SIZE;
   7.154 -      break;
   7.155 -    case OID_GEN_VENDOR_ID:
   7.156 -      temp_data = 0xFFFFFF; // Not guaranteed to be XENSOURCE_MAC_HDR;
   7.157 -      break;
   7.158 -    case OID_GEN_VENDOR_DESCRIPTION:
   7.159 -      data = vendor_desc;
   7.160 -      len = sizeof(vendor_desc);
   7.161 -      break;
   7.162 -    case OID_GEN_CURRENT_PACKET_FILTER:
   7.163 -      temp_data = xi->packet_filter;
   7.164 -      break;
   7.165 -    case OID_GEN_CURRENT_LOOKAHEAD:
   7.166 -      temp_data = xi->current_lookahead;
   7.167 -      break;
   7.168 -    case OID_GEN_DRIVER_VERSION:
   7.169 -      temp_data = (NDIS_MINIPORT_MAJOR_VERSION << 8) | NDIS_MINIPORT_MINOR_VERSION;
   7.170 -      len = 2;
   7.171 -      break;
   7.172 -    case OID_GEN_VENDOR_DRIVER_VERSION:
   7.173 -      temp_data = VENDOR_DRIVER_VERSION;
   7.174 -      len = 4;
   7.175 -      break;
   7.176 -    case OID_GEN_MAXIMUM_TOTAL_SIZE:
   7.177 -      temp_data = xi->config_mtu + XN_HDR_SIZE;
   7.178 -      break;
   7.179 -    case OID_GEN_MAC_OPTIONS:
   7.180 -      temp_data = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | 
   7.181 -        NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
   7.182 -        NDIS_MAC_OPTION_NO_LOOPBACK;
   7.183 -      break;
   7.184 -    case OID_GEN_MEDIA_CONNECT_STATUS:
   7.185 -      if (xi->connected && !xi->inactive)
   7.186 -        temp_data = NdisMediaStateConnected;
   7.187 -      else
   7.188 -        temp_data = NdisMediaStateDisconnected;
   7.189 -      break;
   7.190 -    case OID_GEN_MAXIMUM_SEND_PACKETS:
   7.191 -      /* this is actually ignored for deserialised drivers like us */
   7.192 -      temp_data = 0; //XN_MAX_SEND_PKTS;
   7.193 -      break;
   7.194 -    case OID_GEN_XMIT_OK:
   7.195 -      temp_data = xi->stat_tx_ok;
   7.196 -      HANDLE_STAT_RETURN;
   7.197 -      break;
   7.198 -    case OID_GEN_RCV_OK:
   7.199 -      temp_data = xi->stat_rx_ok;
   7.200 -      HANDLE_STAT_RETURN;
   7.201 -      break;
   7.202 -    case OID_GEN_XMIT_ERROR:
   7.203 -      temp_data = xi->stat_tx_error;
   7.204 -      HANDLE_STAT_RETURN;
   7.205 -      break;
   7.206 -    case OID_GEN_RCV_ERROR:
   7.207 -      temp_data = xi->stat_rx_error;
   7.208 -      HANDLE_STAT_RETURN;
   7.209 -      break;
   7.210 -    case OID_GEN_RCV_NO_BUFFER:
   7.211 -      temp_data = xi->stat_rx_no_buffer;
   7.212 -      HANDLE_STAT_RETURN;
   7.213 -      break;
   7.214 -    case OID_802_3_PERMANENT_ADDRESS:
   7.215 -      data = xi->perm_mac_addr;
   7.216 -      len = ETH_ALEN;
   7.217 -      break;
   7.218 -    case OID_802_3_CURRENT_ADDRESS:
   7.219 -      data = xi->curr_mac_addr;
   7.220 -      len = ETH_ALEN;
   7.221 -      break;
   7.222 -    case OID_802_3_RCV_ERROR_ALIGNMENT:
   7.223 -    case OID_802_3_XMIT_ONE_COLLISION:
   7.224 -    case OID_802_3_XMIT_MORE_COLLISIONS:
   7.225 -      temp_data = 0;
   7.226 -      HANDLE_STAT_RETURN;
   7.227 -      break;
   7.228 -    case OID_802_3_MULTICAST_LIST:
   7.229 -      data = xi->multicast_list;
   7.230 -      len = xi->multicast_list_size * 6;
   7.231 -      break;
   7.232 -    case OID_802_3_MAXIMUM_LIST_SIZE:
   7.233 -      temp_data = MULTICAST_LIST_MAX_SIZE;
   7.234 -      break;
   7.235 -    case OID_TCP_TASK_OFFLOAD:
   7.236 -      KdPrint(("Get OID_TCP_TASK_OFFLOAD\n"));
   7.237 -      /* it's times like this that C really sucks */
   7.238 -
   7.239 -      len = sizeof(NDIS_TASK_OFFLOAD_HEADER);
   7.240 -
   7.241 -      if (xi->config_csum)
   7.242 -      {
   7.243 -        len += FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
   7.244 -          + sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
   7.245 -      }
   7.246 -
   7.247 -      if (xi->config_gso)
   7.248 -      {
   7.249 -        len += FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
   7.250 -          + sizeof(NDIS_TASK_TCP_LARGE_SEND);
   7.251 -      }
   7.252 -
   7.253 -      //len += 1024;
   7.254 -
   7.255 -      if (len > InformationBufferLength)
   7.256 -      {
   7.257 -          break;
   7.258 -      }
   7.259 -
   7.260 -      ntoh = (PNDIS_TASK_OFFLOAD_HEADER)InformationBuffer;
   7.261 -      if (ntoh->Version != NDIS_TASK_OFFLOAD_VERSION
   7.262 -        || ntoh->Size != sizeof(*ntoh)
   7.263 -        || !(
   7.264 -          ntoh->EncapsulationFormat.Encapsulation == IEEE_802_3_Encapsulation
   7.265 -          || (ntoh->EncapsulationFormat.Encapsulation == UNSPECIFIED_Encapsulation
   7.266 -              && ntoh->EncapsulationFormat.EncapsulationHeaderSize == XN_HDR_SIZE)))
   7.267 -      {
   7.268 -        status = NDIS_STATUS_NOT_SUPPORTED;
   7.269 -        break;
   7.270 -      }
   7.271 -      ntoh->OffsetFirstTask = 0; 
   7.272 -      nto = NULL;
   7.273 -
   7.274 -      if (xi->config_csum)
   7.275 -      {
   7.276 -        if (ntoh->OffsetFirstTask == 0)
   7.277 -        {
   7.278 -          ntoh->OffsetFirstTask = ntoh->Size;
   7.279 -          nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(ntoh) + ntoh->OffsetFirstTask);
   7.280 -        }
   7.281 -        else
   7.282 -        {
   7.283 -          nto->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
   7.284 -            + nto->TaskBufferLength;
   7.285 -          nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(nto) + nto->OffsetNextTask);
   7.286 -        }
   7.287 -        /* fill in first nto */
   7.288 -        nto->Version = NDIS_TASK_OFFLOAD_VERSION;
   7.289 -        nto->Size = sizeof(NDIS_TASK_OFFLOAD);
   7.290 -        nto->Task = TcpIpChecksumNdisTask;
   7.291 -        nto->TaskBufferLength = sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
   7.292 -
   7.293 -        KdPrint(("config_csum enabled\n"));
   7.294 -        KdPrint(("nto = %p\n", nto));
   7.295 -        KdPrint(("nto->Size = %d\n", nto->Size));
   7.296 -        KdPrint(("nto->TaskBufferLength = %d\n", nto->TaskBufferLength));
   7.297 -
   7.298 -        /* fill in checksum offload struct */
   7.299 -        nttic = (PNDIS_TASK_TCP_IP_CHECKSUM)nto->TaskBuffer;
   7.300 -        nttic->V4Transmit.IpChecksum = 0;
   7.301 -        nttic->V4Transmit.IpOptionsSupported = 0;
   7.302 -        nttic->V4Transmit.TcpChecksum = 1;
   7.303 -        nttic->V4Transmit.TcpOptionsSupported = 1;
   7.304 -        nttic->V4Transmit.UdpChecksum = 1;
   7.305 -        nttic->V4Receive.IpChecksum = 1;
   7.306 -        nttic->V4Receive.IpOptionsSupported = 1;
   7.307 -        nttic->V4Receive.TcpChecksum = 1;
   7.308 -        nttic->V4Receive.TcpOptionsSupported = 1;
   7.309 -        nttic->V4Receive.UdpChecksum = 1;
   7.310 -        nttic->V6Transmit.IpOptionsSupported = 0;
   7.311 -        nttic->V6Transmit.TcpOptionsSupported = 0;
   7.312 -        nttic->V6Transmit.TcpChecksum = 0;
   7.313 -        nttic->V6Transmit.UdpChecksum = 0;
   7.314 -        nttic->V6Receive.IpOptionsSupported = 0;
   7.315 -        nttic->V6Receive.TcpOptionsSupported = 0;
   7.316 -        nttic->V6Receive.TcpChecksum = 0;
   7.317 -        nttic->V6Receive.UdpChecksum = 0;
   7.318 -      }
   7.319 -      if (xi->config_gso)
   7.320 -      {
   7.321 -        if (ntoh->OffsetFirstTask == 0)
   7.322 -        {
   7.323 -          ntoh->OffsetFirstTask = ntoh->Size;
   7.324 -          nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(ntoh) + ntoh->OffsetFirstTask);
   7.325 -        }
   7.326 -        else
   7.327 -        {
   7.328 -          nto->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
   7.329 -            + nto->TaskBufferLength;
   7.330 -          nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(nto) + nto->OffsetNextTask);
   7.331 -        }
   7.332 -  
   7.333 -        /* fill in second nto */
   7.334 -        nto->Version = NDIS_TASK_OFFLOAD_VERSION;
   7.335 -        nto->Size = sizeof(NDIS_TASK_OFFLOAD);
   7.336 -        nto->Task = TcpLargeSendNdisTask;
   7.337 -        nto->TaskBufferLength = sizeof(NDIS_TASK_TCP_LARGE_SEND);
   7.338 -
   7.339 -        KdPrint(("config_gso enabled\n"));
   7.340 -        KdPrint(("nto = %p\n", nto));
   7.341 -        KdPrint(("nto->Size = %d\n", nto->Size));
   7.342 -        KdPrint(("nto->TaskBufferLength = %d\n", nto->TaskBufferLength));
   7.343 -  
   7.344 -        /* fill in large send struct */
   7.345 -        nttls = (PNDIS_TASK_TCP_LARGE_SEND)nto->TaskBuffer;
   7.346 -        nttls->Version = 0;
   7.347 -        nttls->MaxOffLoadSize = xi->config_gso;
   7.348 -        nttls->MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
   7.349 -        nttls->TcpOptions = FALSE; /* linux can't handle this */
   7.350 -        nttls->IpOptions = FALSE; /* linux can't handle this */
   7.351 -        KdPrint(("&(nttls->IpOptions) = %p\n", &(nttls->IpOptions)));        
   7.352 -      }
   7.353 -
   7.354 -      if (nto)
   7.355 -        nto->OffsetNextTask = 0; /* last one */
   7.356 -
   7.357 -      used_temp_buffer = FALSE;
   7.358 -      break;
   7.359 -    case OID_IP4_OFFLOAD_STATS:
   7.360 -    case OID_IP6_OFFLOAD_STATS:
   7.361 -      /* these are called often so just ignore then quietly */
   7.362 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.363 -      break;
   7.364 -
   7.365 -    case OID_PNP_CAPABILITIES:
   7.366 -      KdPrint(("Get OID_PNP_CAPABILITIES\n"));
   7.367 -      len = sizeof(NDIS_PNP_CAPABILITIES);
   7.368 -      if (len > InformationBufferLength)
   7.369 -        break;
   7.370 -      npc = (PNDIS_PNP_CAPABILITIES)InformationBuffer;
   7.371 -      npc->Flags = 0;
   7.372 -      npc->WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
   7.373 -      npc->WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateUnspecified;
   7.374 -      npc->WakeUpCapabilities.MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
   7.375 -      used_temp_buffer = FALSE;
   7.376 -      break;
   7.377 -    case OID_PNP_QUERY_POWER:
   7.378 -      KdPrint(("Get OID_PNP_CAPABILITIES\n"));
   7.379 -      used_temp_buffer = FALSE;
   7.380 -      break;
   7.381 -
   7.382 -    default:
   7.383 -      KdPrint(("Get Unknown OID 0x%x\n", Oid));
   7.384 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.385 -  }
   7.386 -
   7.387 -  if (!NT_SUCCESS(status))
   7.388 -  {
   7.389 -    //FUNCTION_EXIT_STATUS(status);
   7.390 -    return status;
   7.391 -  }
   7.392 -
   7.393 -  if (len > InformationBufferLength)
   7.394 -  {
   7.395 -    *BytesNeeded = len;
   7.396 -    FUNCTION_MSG("(BUFFER_TOO_SHORT %d > %d)\n", len, InformationBufferLength);
   7.397 -    return NDIS_STATUS_BUFFER_TOO_SHORT;
   7.398 -  }
   7.399 -
   7.400 -  *BytesWritten = len;
   7.401 -  if (len && used_temp_buffer)
   7.402 -  {
   7.403 -    NdisMoveMemory((PUCHAR)InformationBuffer, data, len);
   7.404 -  }
   7.405 -
   7.406 -  //KdPrint(("Got OID 0x%x\n", Oid));
   7.407 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   7.408 -
   7.409 -  return status;
   7.410 -}
   7.411 -
   7.412 -NDIS_STATUS
   7.413 -XenNet_SetInformation(
   7.414 -  IN NDIS_HANDLE MiniportAdapterContext,
   7.415 -  IN NDIS_OID Oid,
   7.416 -  IN PVOID InformationBuffer,
   7.417 -  IN ULONG InformationBufferLength,
   7.418 -  OUT PULONG BytesRead,
   7.419 -  OUT PULONG BytesNeeded
   7.420 -  )
   7.421 -{
   7.422 -  NTSTATUS status;
   7.423 -  ULONG i;
   7.424 -  struct xennet_info *xi = MiniportAdapterContext;
   7.425 -  PULONG64 data = InformationBuffer;
   7.426 -  PNDIS_TASK_OFFLOAD_HEADER ntoh;
   7.427 -  PNDIS_TASK_OFFLOAD nto;
   7.428 -  PNDIS_TASK_TCP_IP_CHECKSUM nttic = NULL;
   7.429 -  PNDIS_TASK_TCP_LARGE_SEND nttls = NULL;
   7.430 -  UCHAR *multicast_list;
   7.431 -  int offset;
   7.432 -
   7.433 -  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   7.434 -
   7.435 -  UNREFERENCED_PARAMETER(MiniportAdapterContext);
   7.436 -  UNREFERENCED_PARAMETER(InformationBufferLength);
   7.437 -  UNREFERENCED_PARAMETER(BytesRead);
   7.438 -  UNREFERENCED_PARAMETER(BytesNeeded);
   7.439 -
   7.440 -  switch(Oid)
   7.441 -  {
   7.442 -    case OID_GEN_SUPPORTED_LIST:
   7.443 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.444 -      KdPrint(("Unsupported set OID_GEN_SUPPORTED_LIST\n"));
   7.445 -      break;
   7.446 -    case OID_GEN_HARDWARE_STATUS:
   7.447 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.448 -      KdPrint(("Unsupported set OID_GEN_HARDWARE_STATUS\n"));
   7.449 -      break;
   7.450 -    case OID_GEN_MEDIA_SUPPORTED:
   7.451 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.452 -      KdPrint(("Unsupported set OID_GEN_MEDIA_SUPPORTED\n"));
   7.453 -      break;
   7.454 -    case OID_GEN_MEDIA_IN_USE:
   7.455 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.456 -      KdPrint(("Unsupported set OID_GEN_MEDIA_IN_USE\n"));
   7.457 -      break;
   7.458 -    case OID_GEN_MAXIMUM_LOOKAHEAD:
   7.459 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.460 -      KdPrint(("Unsupported set OID_GEN_MAXIMUM_LOOKAHEAD %d\n", *(ULONG *)data));
   7.461 -      break;
   7.462 -    case OID_GEN_MAXIMUM_FRAME_SIZE:
   7.463 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.464 -      KdPrint(("Unsupported set OID_GEN_MAXIMUM_FRAME_SIZE\n"));
   7.465 -      break;
   7.466 -    case OID_GEN_LINK_SPEED:
   7.467 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.468 -      KdPrint(("Unsupported set OID_GEN_LINK_SPEED\n"));
   7.469 -      break;
   7.470 -    case OID_GEN_TRANSMIT_BUFFER_SPACE:
   7.471 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.472 -      KdPrint(("Unsupported set OID_GEN_TRANSMIT_BUFFER_SPACE\n"));
   7.473 -      break;
   7.474 -    case OID_GEN_RECEIVE_BUFFER_SPACE:
   7.475 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.476 -      KdPrint(("Unsupported set OID_GEN_RECEIVE_BUFFER_SPACE\n"));
   7.477 -      break;
   7.478 -    case OID_GEN_TRANSMIT_BLOCK_SIZE:
   7.479 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.480 -      KdPrint(("Unsupported set OID_GEN_TRANSMIT_BLOCK_SIZE\n"));
   7.481 -      break;
   7.482 -    case OID_GEN_RECEIVE_BLOCK_SIZE:
   7.483 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.484 -      KdPrint(("Unsupported set OID_GEN_RECEIVE_BLOCK_SIZE\n"));
   7.485 -      break;
   7.486 -    case OID_GEN_VENDOR_ID:
   7.487 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.488 -      KdPrint(("Unsupported set OID_GEN_VENDOR_ID\n"));
   7.489 -      break;
   7.490 -    case OID_GEN_VENDOR_DESCRIPTION:
   7.491 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.492 -      KdPrint(("Unsupported set OID_GEN_VENDOR_DESCRIPTION\n"));
   7.493 -      break;
   7.494 -    case OID_GEN_CURRENT_PACKET_FILTER:
   7.495 -      KdPrint(("Set OID_GEN_CURRENT_PACKET_FILTER (xi = %p)\n", xi));
   7.496 -      if (*(ULONG *)data & NDIS_PACKET_TYPE_DIRECTED)
   7.497 -        KdPrint(("  NDIS_PACKET_TYPE_DIRECTED\n"));
   7.498 -      if (*(ULONG *)data & NDIS_PACKET_TYPE_MULTICAST)
   7.499 -        KdPrint(("  NDIS_PACKET_TYPE_MULTICAST\n"));
   7.500 -      if (*(ULONG *)data & NDIS_PACKET_TYPE_ALL_MULTICAST)
   7.501 -        KdPrint(("  NDIS_PACKET_TYPE_ALL_MULTICAST\n"));
   7.502 -      if (*(ULONG *)data & NDIS_PACKET_TYPE_BROADCAST)
   7.503 -        KdPrint(("  NDIS_PACKET_TYPE_BROADCAST\n"));
   7.504 -      if (*(ULONG *)data & NDIS_PACKET_TYPE_PROMISCUOUS)
   7.505 -        KdPrint(("  NDIS_PACKET_TYPE_PROMISCUOUS\n"));
   7.506 -      if (*(ULONG *)data & NDIS_PACKET_TYPE_ALL_FUNCTIONAL)
   7.507 -        KdPrint(("  NDIS_PACKET_TYPE_ALL_FUNCTIONAL (not supported)\n"));
   7.508 -      if (*(ULONG *)data & NDIS_PACKET_TYPE_ALL_LOCAL)
   7.509 -        KdPrint(("  NDIS_PACKET_TYPE_ALL_LOCAL (not supported)\n"));  
   7.510 -      if (*(ULONG *)data & NDIS_PACKET_TYPE_FUNCTIONAL)
   7.511 -        KdPrint(("  NDIS_PACKET_TYPE_FUNCTIONAL (not supported)\n"));
   7.512 -      if (*(ULONG *)data & NDIS_PACKET_TYPE_GROUP)
   7.513 -        KdPrint(("  NDIS_PACKET_TYPE_GROUP (not supported)\n"));
   7.514 -      if (*(ULONG *)data & ~SUPPORTED_PACKET_FILTERS)
   7.515 -      {
   7.516 -        status = NDIS_STATUS_NOT_SUPPORTED;
   7.517 -        KdPrint(("  returning NDIS_STATUS_NOT_SUPPORTED\n"));
   7.518 -        break;
   7.519 -      }
   7.520 -      xi->packet_filter = *(ULONG *)data;
   7.521 -      status = NDIS_STATUS_SUCCESS;
   7.522 -      break;
   7.523 -    case OID_GEN_CURRENT_LOOKAHEAD:
   7.524 -      xi->current_lookahead = *(ULONG *)data;
   7.525 -      KdPrint(("Set OID_GEN_CURRENT_LOOKAHEAD %d (%p)\n", xi->current_lookahead, xi));
   7.526 -      status = NDIS_STATUS_SUCCESS;
   7.527 -      break;
   7.528 -    case OID_GEN_DRIVER_VERSION:
   7.529 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.530 -      KdPrint(("Unsupported set OID_GEN_DRIVER_VERSION\n"));
   7.531 -      break;
   7.532 -    case OID_GEN_MAXIMUM_TOTAL_SIZE:
   7.533 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.534 -      KdPrint(("Unsupported set OID_GEN_MAXIMUM_TOTAL_SIZE\n"));
   7.535 -      break;
   7.536 -    case OID_GEN_PROTOCOL_OPTIONS:
   7.537 -      KdPrint(("Unsupported set OID_GEN_PROTOCOL_OPTIONS\n"));
   7.538 -      // TODO - actually do this...
   7.539 -      status = NDIS_STATUS_SUCCESS;
   7.540 -      break;
   7.541 -    case OID_GEN_MAC_OPTIONS:
   7.542 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.543 -      KdPrint(("Unsupported set OID_GEN_MAC_OPTIONS\n"));
   7.544 -      break;
   7.545 -    case OID_GEN_MEDIA_CONNECT_STATUS:
   7.546 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.547 -      KdPrint(("Unsupported set OID_GEN_MEDIA_CONNECT_STATUS\n"));
   7.548 -      break;
   7.549 -    case OID_GEN_MAXIMUM_SEND_PACKETS:
   7.550 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.551 -      KdPrint(("Unsupported set OID_GEN_MAXIMUM_SEND_PACKETS\n"));
   7.552 -      break;
   7.553 -    case OID_GEN_XMIT_OK:
   7.554 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.555 -      KdPrint(("Unsupported set OID_GEN_XMIT_OK\n"));
   7.556 -      break;
   7.557 -    case OID_GEN_RCV_OK:
   7.558 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.559 -      KdPrint(("Unsupported set OID_GEN_RCV_OK\n"));
   7.560 -      break;
   7.561 -    case OID_GEN_XMIT_ERROR:
   7.562 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.563 -      KdPrint(("Unsupported set OID_GEN_XMIT_ERROR\n"));
   7.564 -      break;
   7.565 -    case OID_GEN_RCV_ERROR:
   7.566 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.567 -      KdPrint(("Unsupported set OID_GEN_RCV_ERROR\n"));
   7.568 -      break;
   7.569 -    case OID_GEN_RCV_NO_BUFFER:
   7.570 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.571 -      KdPrint(("Unsupported set OID_GEN_RCV_NO_BUFFER\n"));
   7.572 -      break;
   7.573 -    case OID_802_3_PERMANENT_ADDRESS:
   7.574 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.575 -      KdPrint(("Unsupported set OID_802_3_PERMANENT_ADDRESS\n"));
   7.576 -      break;
   7.577 -    case OID_802_3_CURRENT_ADDRESS:
   7.578 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.579 -      KdPrint(("Unsupported set OID_802_3_CURRENT_ADDRESS\n"));
   7.580 -      break;
   7.581 -    case OID_802_3_MULTICAST_LIST:
   7.582 -      KdPrint(("     Set OID_802_3_MULTICAST_LIST\n"));
   7.583 -      KdPrint(("       Length = %d\n", InformationBufferLength));
   7.584 -      KdPrint(("       Entries = %d\n", InformationBufferLength / 6));
   7.585 -      if (InformationBufferLength > MULTICAST_LIST_MAX_SIZE * 6)
   7.586 -      {
   7.587 -        status = NDIS_STATUS_MULTICAST_FULL;
   7.588 -        break;
   7.589 -      }
   7.590 -      
   7.591 -      if (InformationBufferLength % 6 != 0)
   7.592 -      {
   7.593 -        status = NDIS_STATUS_MULTICAST_FULL;
   7.594 -        break;
   7.595 -      }
   7.596 -      multicast_list = InformationBuffer;
   7.597 -      for (i = 0; i < InformationBufferLength / 6; i++)
   7.598 -      {
   7.599 -        if (!(multicast_list[i * 6 + 0] & 0x01))
   7.600 -        {
   7.601 -          KdPrint(("       Address %d (%02x:%02x:%02x:%02x:%02x:%02x) is not a multicast address\n", i,
   7.602 -            (ULONG)multicast_list[i * 6 + 0], (ULONG)multicast_list[i * 6 + 1], 
   7.603 -            (ULONG)multicast_list[i * 6 + 2], (ULONG)multicast_list[i * 6 + 3], 
   7.604 -            (ULONG)multicast_list[i * 6 + 4], (ULONG)multicast_list[i * 6 + 5]));
   7.605 -          /* the docs say that we should return NDIS_STATUS_MULTICAST_FULL if we get an invalid multicast address but I'm not sure if that's the case... */
   7.606 -        }
   7.607 -      }
   7.608 -      memcpy(xi->multicast_list, InformationBuffer, InformationBufferLength);
   7.609 -      xi->multicast_list_size = InformationBufferLength / 6;
   7.610 -      status = NDIS_STATUS_SUCCESS;
   7.611 -      break;
   7.612 -    case OID_802_3_MAXIMUM_LIST_SIZE:
   7.613 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.614 -      KdPrint(("Unsupported set OID_802_3_MAXIMUM_LIST_SIZE\n"));
   7.615 -      break;
   7.616 -    case OID_TCP_TASK_OFFLOAD:
   7.617 -      status = NDIS_STATUS_SUCCESS;
   7.618 -      KdPrint(("Set OID_TCP_TASK_OFFLOAD\n"));
   7.619 -      // we should disable everything here, then enable what has been set
   7.620 -      ntoh = (PNDIS_TASK_OFFLOAD_HEADER)InformationBuffer;
   7.621 -      if (ntoh->Version != NDIS_TASK_OFFLOAD_VERSION)
   7.622 -      {
   7.623 -        KdPrint(("Invalid version (%d passed but must be %d)\n", ntoh->Version, NDIS_TASK_OFFLOAD_VERSION));
   7.624 -        status = NDIS_STATUS_INVALID_DATA;
   7.625 -        break;
   7.626 -      }
   7.627 -      if (ntoh->Version != NDIS_TASK_OFFLOAD_VERSION || ntoh->Size != sizeof(NDIS_TASK_OFFLOAD_HEADER))
   7.628 -      {
   7.629 -        KdPrint(("Invalid size (%d passed but must be %d)\n", ntoh->Size, sizeof(NDIS_TASK_OFFLOAD_HEADER)));
   7.630 -        status = NDIS_STATUS_INVALID_DATA;
   7.631 -        break;
   7.632 -      }
   7.633 -      *BytesRead = sizeof(NDIS_TASK_OFFLOAD_HEADER);
   7.634 -      offset = ntoh->OffsetFirstTask;
   7.635 -      nto = (PNDIS_TASK_OFFLOAD)ntoh; // not really, just to get the first offset right
   7.636 -      while (offset != 0)
   7.637 -      {
   7.638 -        *BytesRead += FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer);
   7.639 -        nto = (PNDIS_TASK_OFFLOAD)(((PUCHAR)nto) + offset);
   7.640 -        switch (nto->Task)
   7.641 -        {
   7.642 -        case TcpIpChecksumNdisTask:
   7.643 -          *BytesRead += sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
   7.644 -          nttic = (PNDIS_TASK_TCP_IP_CHECKSUM)nto->TaskBuffer;
   7.645 -          KdPrint(("TcpIpChecksumNdisTask\n"));
   7.646 -          KdPrint(("  V4Transmit.IpOptionsSupported  = %d\n", nttic->V4Transmit.IpOptionsSupported));
   7.647 -          KdPrint(("  V4Transmit.TcpOptionsSupported = %d\n", nttic->V4Transmit.TcpOptionsSupported));
   7.648 -          KdPrint(("  V4Transmit.TcpChecksum         = %d\n", nttic->V4Transmit.TcpChecksum));
   7.649 -          KdPrint(("  V4Transmit.UdpChecksum         = %d\n", nttic->V4Transmit.UdpChecksum));
   7.650 -          KdPrint(("  V4Transmit.IpChecksum          = %d\n", nttic->V4Transmit.IpChecksum));
   7.651 -          KdPrint(("  V4Receive.IpOptionsSupported   = %d\n", nttic->V4Receive.IpOptionsSupported));
   7.652 -          KdPrint(("  V4Receive.TcpOptionsSupported  = %d\n", nttic->V4Receive.TcpOptionsSupported));
   7.653 -          KdPrint(("  V4Receive.TcpChecksum          = %d\n", nttic->V4Receive.TcpChecksum));
   7.654 -          KdPrint(("  V4Receive.UdpChecksum          = %d\n", nttic->V4Receive.UdpChecksum));
   7.655 -          KdPrint(("  V4Receive.IpChecksum           = %d\n", nttic->V4Receive.IpChecksum));
   7.656 -          KdPrint(("  V6Transmit.IpOptionsSupported  = %d\n", nttic->V6Transmit.IpOptionsSupported));
   7.657 -          KdPrint(("  V6Transmit.TcpOptionsSupported = %d\n", nttic->V6Transmit.TcpOptionsSupported));
   7.658 -          KdPrint(("  V6Transmit.TcpChecksum         = %d\n", nttic->V6Transmit.TcpChecksum));
   7.659 -          KdPrint(("  V6Transmit.UdpChecksum         = %d\n", nttic->V6Transmit.UdpChecksum));
   7.660 -          KdPrint(("  V6Receive.IpOptionsSupported   = %d\n", nttic->V6Receive.IpOptionsSupported));
   7.661 -          KdPrint(("  V6Receive.TcpOptionsSupported  = %d\n", nttic->V6Receive.TcpOptionsSupported));
   7.662 -          KdPrint(("  V6Receive.TcpChecksum          = %d\n", nttic->V6Receive.TcpChecksum));
   7.663 -          KdPrint(("  V6Receive.UdpChecksum          = %d\n", nttic->V6Receive.UdpChecksum));
   7.664 -          /* check for stuff we outright don't support */
   7.665 -          if (nttic->V6Transmit.IpOptionsSupported ||
   7.666 -            nttic->V6Transmit.TcpOptionsSupported ||
   7.667 -            nttic->V6Transmit.TcpChecksum ||
   7.668 -            nttic->V6Transmit.UdpChecksum ||
   7.669 -            nttic->V6Receive.IpOptionsSupported ||
   7.670 -            nttic->V6Receive.TcpOptionsSupported ||
   7.671 -            nttic->V6Receive.TcpChecksum ||
   7.672 -            nttic->V6Receive.UdpChecksum)
   7.673 -          {
   7.674 -            KdPrint(("IPv6 offload not supported\n"));
   7.675 -            status = NDIS_STATUS_INVALID_DATA;
   7.676 -            nttic = NULL;
   7.677 -            break;
   7.678 -          }
   7.679 -          if (nttic->V4Transmit.IpOptionsSupported ||
   7.680 -            nttic->V4Transmit.IpChecksum)
   7.681 -          {
   7.682 -            KdPrint(("IPv4 IP Transmit offload not supported\n"));
   7.683 -            status = NDIS_STATUS_INVALID_DATA;
   7.684 -            nttic = NULL;
   7.685 -            break;
   7.686 -          }
   7.687 -          if (nttic->V4Receive.IpOptionsSupported &&
   7.688 -            !nttic->V4Receive.IpChecksum)
   7.689 -          {
   7.690 -            KdPrint(("Invalid combination\n"));
   7.691 -            status = NDIS_STATUS_INVALID_DATA;
   7.692 -            nttic = NULL;
   7.693 -            break;
   7.694 -          }
   7.695 -          if (nttic->V4Transmit.TcpOptionsSupported &&
   7.696 -            !nttic->V4Transmit.TcpChecksum)
   7.697 -          {
   7.698 -            KdPrint(("Invalid combination\n"));
   7.699 -            status = NDIS_STATUS_INVALID_DATA;
   7.700 -            nttic = NULL;
   7.701 -            break;
   7.702 -          }
   7.703 -          if (nttic->V4Receive.TcpOptionsSupported &&
   7.704 -            !nttic->V4Receive.TcpChecksum)
   7.705 -          {
   7.706 -            KdPrint(("Invalid combination\n"));
   7.707 -            status = NDIS_STATUS_INVALID_DATA;
   7.708 -            nttic = NULL;
   7.709 -            break;
   7.710 -          }
   7.711 -          break;
   7.712 -        case TcpLargeSendNdisTask:
   7.713 -          *BytesRead += sizeof(NDIS_TASK_TCP_LARGE_SEND);
   7.714 -          KdPrint(("TcpLargeSendNdisTask\n"));
   7.715 -          nttls = (PNDIS_TASK_TCP_LARGE_SEND)nto->TaskBuffer;
   7.716 -          KdPrint(("  MaxOffLoadSize                 = %d\n", nttls->MaxOffLoadSize));
   7.717 -          KdPrint(("  MinSegmentCount                = %d\n", nttls->MinSegmentCount));
   7.718 -          KdPrint(("  TcpOptions                     = %d\n", nttls->TcpOptions));
   7.719 -          KdPrint(("  IpOptions                      = %d\n", nttls->IpOptions));
   7.720 -          if (nttls->MinSegmentCount != MIN_LARGE_SEND_SEGMENTS)
   7.721 -          {
   7.722 -            KdPrint(("     MinSegmentCount should be %d\n", MIN_LARGE_SEND_SEGMENTS));
   7.723 -            status = NDIS_STATUS_INVALID_DATA;
   7.724 -            nttls = NULL;
   7.725 -            break;
   7.726 -          }
   7.727 -          if (nttls->IpOptions)
   7.728 -          {
   7.729 -            KdPrint(("     IpOptions not supported\n"));
   7.730 -            status = NDIS_STATUS_INVALID_DATA;
   7.731 -            nttls = NULL;
   7.732 -            break;
   7.733 -          }
   7.734 -          if (nttls->TcpOptions)
   7.735 -          {
   7.736 -            KdPrint(("     TcpOptions not supported\n"));
   7.737 -            status = NDIS_STATUS_INVALID_DATA;
   7.738 -            nttls = NULL;
   7.739 -            break;
   7.740 -          }
   7.741 -          break;
   7.742 -        default:
   7.743 -          KdPrint(("     Unknown Task %d\n", nto->Task));
   7.744 -        }
   7.745 -        offset = nto->OffsetNextTask;
   7.746 -      }
   7.747 -      if (nttic != NULL)
   7.748 -        xi->setting_csum = *nttic;
   7.749 -      else
   7.750 -      {
   7.751 -        RtlZeroMemory(&xi->setting_csum, sizeof(NDIS_TASK_TCP_IP_CHECKSUM));
   7.752 -        KdPrint(("     csum offload disabled\n", nto->Task));
   7.753 -      }        
   7.754 -      if (nttls != NULL)
   7.755 -        xi->setting_max_offload = nttls->MaxOffLoadSize;
   7.756 -      else
   7.757 -      {
   7.758 -        xi->setting_max_offload = 0;
   7.759 -        KdPrint(("     LSO disabled\n", nto->Task));
   7.760 -      }
   7.761 -      break;
   7.762 -    case OID_PNP_SET_POWER:
   7.763 -      KdPrint(("     Set OID_PNP_SET_POWER\n"));
   7.764 -      xi->new_power_state = *(PNDIS_DEVICE_POWER_STATE)InformationBuffer;
   7.765 -      IoQueueWorkItem(xi->power_workitem, XenNet_SetPower, DelayedWorkQueue, xi);
   7.766 -      status = NDIS_STATUS_PENDING;
   7.767 -      break;
   7.768 -    default:
   7.769 -      KdPrint(("Set Unknown OID 0x%x\n", Oid));
   7.770 -      status = NDIS_STATUS_NOT_SUPPORTED;
   7.771 -      break;
   7.772 -  }
   7.773 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   7.774 -  return status;
   7.775 -}
     8.1 --- a/xennet/xennet5_rx.c	Sun Feb 10 23:12:03 2013 +1100
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,1185 +0,0 @@
     8.4 -/*
     8.5 -PV Net Driver for Windows Xen HVM Domains
     8.6 -Copyright (C) 2007 James Harper
     8.7 -Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
     8.8 -
     8.9 -This program is free software; you can redistribute it and/or
    8.10 -modify it under the terms of the GNU General Public License
    8.11 -as published by the Free Software Foundation; either version 2
    8.12 -of the License, or (at your option) any later version.
    8.13 -
    8.14 -This program is distributed in the hope that it will be useful,
    8.15 -but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.16 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.17 -GNU General Public License for more details.
    8.18 -
    8.19 -You should have received a copy of the GNU General Public License
    8.20 -along with this program; if not, write to the Free Software
    8.21 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    8.22 -*/
    8.23 -
    8.24 -#include "xennet5.h"
    8.25 -
    8.26 -static __inline shared_buffer_t *
    8.27 -get_pb_from_freelist(struct xennet_info *xi)
    8.28 -{
    8.29 -  NDIS_STATUS status;
    8.30 -  shared_buffer_t *pb;
    8.31 -  PVOID ptr_ref;
    8.32 -
    8.33 -  if (stack_pop(xi->rx_pb_stack, &ptr_ref))
    8.34 -  {
    8.35 -    pb = ptr_ref;
    8.36 -    pb->ref_count = 1;
    8.37 -    InterlockedDecrement(&xi->rx_pb_free);
    8.38 -    return pb;
    8.39 -  }
    8.40 -
    8.41 -  /* don't allocate a new one if we are shutting down */
    8.42 -  if (xi->shutting_down)
    8.43 -    return NULL;
    8.44 -    
    8.45 -  status = NdisAllocateMemoryWithTag(&pb, sizeof(shared_buffer_t), XENNET_POOL_TAG);
    8.46 -  if (status != STATUS_SUCCESS)
    8.47 -  {
    8.48 -    return NULL;
    8.49 -  }
    8.50 -  status = NdisAllocateMemoryWithTag(&pb->virtual, PAGE_SIZE, XENNET_POOL_TAG);
    8.51 -  if (status != STATUS_SUCCESS)
    8.52 -  {
    8.53 -    NdisFreeMemory(pb, sizeof(shared_buffer_t), 0);
    8.54 -    return NULL;
    8.55 -  }
    8.56 -  pb->gref = (grant_ref_t)xi->vectors.GntTbl_GrantAccess(xi->vectors.context,
    8.57 -            (ULONG)(MmGetPhysicalAddress(pb->virtual).QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, (ULONG)'XNRX');
    8.58 -  if (pb->gref == INVALID_GRANT_REF)
    8.59 -  {
    8.60 -    NdisFreeMemory(pb, sizeof(shared_buffer_t), 0);
    8.61 -    NdisFreeMemory(pb->virtual, PAGE_SIZE, 0);
    8.62 -    return NULL;
    8.63 -  }
    8.64 -  pb->offset = (USHORT)(ULONG_PTR)pb->virtual & (PAGE_SIZE - 1);
    8.65 -  NdisAllocateBuffer(&status, &pb->buffer, xi->rx_buffer_pool, (PUCHAR)pb->virtual, PAGE_SIZE);
    8.66 -  if (status != STATUS_SUCCESS)
    8.67 -  {
    8.68 -    xi->vectors.GntTbl_EndAccess(xi->vectors.context,
    8.69 -        pb->gref, FALSE, (ULONG)'XNRX');
    8.70 -    NdisFreeMemory(pb, sizeof(shared_buffer_t), 0);
    8.71 -    NdisFreeMemory(pb->virtual, PAGE_SIZE, 0);
    8.72 -    return NULL;
    8.73 -  }
    8.74 -  pb->ref_count = 1;
    8.75 -  return pb;
    8.76 -}
    8.77 -
    8.78 -static __inline VOID
    8.79 -ref_pb(struct xennet_info *xi, shared_buffer_t *pb)
    8.80 -{
    8.81 -  UNREFERENCED_PARAMETER(xi);
    8.82 -  InterlockedIncrement(&pb->ref_count);
    8.83 -}
    8.84 -
    8.85 -static __inline VOID
    8.86 -put_pb_on_freelist(struct xennet_info *xi, shared_buffer_t *pb)
    8.87 -{
    8.88 -  if (InterlockedDecrement(&pb->ref_count) == 0)
    8.89 -  {
    8.90 -    NdisAdjustBufferLength(pb->buffer, PAGE_SIZE);
    8.91 -    NDIS_BUFFER_LINKAGE(pb->buffer) = NULL;
    8.92 -    pb->next = NULL;
    8.93 -    stack_push(xi->rx_pb_stack, pb);
    8.94 -    InterlockedIncrement(&xi->rx_pb_free);
    8.95 -  }
    8.96 -}
    8.97 -
    8.98 -// Called at DISPATCH_LEVEL with rx lock held
    8.99 -static NDIS_STATUS
   8.100 -XenNet_FillRing(struct xennet_info *xi)
   8.101 -{
   8.102 -  unsigned short id;
   8.103 -  shared_buffer_t *page_buf;
   8.104 -  ULONG i, notify;
   8.105 -  ULONG batch_target;
   8.106 -  RING_IDX req_prod = xi->rx.req_prod_pvt;
   8.107 -  netif_rx_request_t *req;
   8.108 -
   8.109 -  //FUNCTION_ENTER();
   8.110 -
   8.111 -  batch_target = xi->rx_target - (req_prod - xi->rx.rsp_cons);
   8.112 -
   8.113 -  if (batch_target < (xi->rx_target >> 2))
   8.114 -  {
   8.115 -    //FUNCTION_EXIT();
   8.116 -    return NDIS_STATUS_SUCCESS; /* only refill if we are less than 3/4 full already */
   8.117 -  }
   8.118 -
   8.119 -  for (i = 0; i < batch_target; i++)
   8.120 -  {
   8.121 -    page_buf = get_pb_from_freelist(xi);
   8.122 -    if (!page_buf)
   8.123 -    {
   8.124 -      KdPrint((__DRIVER_NAME "     Added %d out of %d buffers to rx ring (no free pages)\n", i, batch_target));
   8.125 -      break;
   8.126 -    }
   8.127 -    xi->rx_id_free--;
   8.128 -
   8.129 -    /* Give to netback */
   8.130 -    id = (USHORT)((req_prod + i) & (NET_RX_RING_SIZE - 1));
   8.131 -    ASSERT(xi->rx_ring_pbs[id] == NULL);
   8.132 -    xi->rx_ring_pbs[id] = page_buf;
   8.133 -    req = RING_GET_REQUEST(&xi->rx, req_prod + i);
   8.134 -    req->id = id;
   8.135 -    req->gref = page_buf->gref;
   8.136 -    ASSERT(req->gref != INVALID_GRANT_REF);
   8.137 -  }
   8.138 -  KeMemoryBarrier();
   8.139 -  xi->rx.req_prod_pvt = req_prod + i;
   8.140 -  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xi->rx, notify);
   8.141 -  if (notify)
   8.142 -  {
   8.143 -    xi->vectors.EvtChn_Notify(xi->vectors.context, xi->event_channel);
   8.144 -  }
   8.145 -
   8.146 -  //FUNCTION_EXIT();
   8.147 -
   8.148 -  return NDIS_STATUS_SUCCESS;
   8.149 -}
   8.150 -
   8.151 -/* lock free */
   8.152 -static PNDIS_PACKET
   8.153 -get_packet_from_freelist(struct xennet_info *xi)
   8.154 -{
   8.155 -  NDIS_STATUS status;
   8.156 -  PNDIS_PACKET packet;
   8.157 -  PVOID ptr_ref;
   8.158 -
   8.159 -  if (stack_pop(xi->rx_packet_stack, &ptr_ref))
   8.160 -  {
   8.161 -    packet = ptr_ref;
   8.162 -    return packet;
   8.163 -  }
   8.164 -  
   8.165 -  if (xi->rx_shutting_down) /* don't keep allocating new packets on shutdown */
   8.166 -    return NULL;
   8.167 -
   8.168 -  NdisAllocatePacket(&status, &packet, xi->rx_packet_pool);
   8.169 -  if (status != NDIS_STATUS_SUCCESS) {
   8.170 -    KdPrint((__DRIVER_NAME "     cannot allocate packet status = %08x, rx_outstanding = %d\n", status, xi->rx_outstanding));
   8.171 -    return NULL;
   8.172 -  }
   8.173 -  NDIS_SET_PACKET_HEADER_SIZE(packet, XN_HDR_SIZE);
   8.174 -  NdisZeroMemory(packet->MiniportReservedEx, sizeof(packet->MiniportReservedEx));
   8.175 -  return packet;
   8.176 -}
   8.177 -
   8.178 -/* lock free */
   8.179 -static VOID
   8.180 -put_packet_on_freelist(struct xennet_info *xi, PNDIS_PACKET packet)
   8.181 -{
   8.182 -  PNDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
   8.183 -
   8.184 -  UNREFERENCED_PARAMETER(xi);
   8.185 -  NdisReinitializePacket(packet);
   8.186 -  csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
   8.187 -    packet, TcpIpChecksumPacketInfo);
   8.188 -  csum_info->Value = 0;
   8.189 -
   8.190 -  stack_push(xi->rx_packet_stack, packet);
   8.191 -}
   8.192 -
   8.193 -static PNDIS_PACKET
   8.194 -XenNet_MakePacket(struct xennet_info *xi, packet_info_t *pi)
   8.195 -{
   8.196 -  NDIS_STATUS status;
   8.197 -  PNDIS_PACKET packet;
   8.198 -  PNDIS_BUFFER out_buffer;
   8.199 -  USHORT new_ip4_length;
   8.200 -  PUCHAR header_va;
   8.201 -  ULONG out_remaining;
   8.202 -  ULONG tcp_length;
   8.203 -  ULONG header_extra;
   8.204 -  ULONG packet_length = 0;
   8.205 -  shared_buffer_t *header_buf;
   8.206 -
   8.207 -  //FUNCTION_ENTER();
   8.208 -  
   8.209 -  packet = get_packet_from_freelist(xi);
   8.210 -  if (packet == NULL)
   8.211 -  {
   8.212 -    /* buffers will be freed in MakePackets */
   8.213 -    //KdPrint((__DRIVER_NAME "     No free packets\n"));
   8.214 -    //FUNCTION_EXIT();
   8.215 -    return NULL;
   8.216 -  }
   8.217 -
   8.218 -  if (!pi->split_required && pi->mdl_count == 1)
   8.219 -  {
   8.220 -    /* shortcut for the single packet single mdl case */
   8.221 -    
   8.222 -    NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
   8.223 -    NdisCopyBuffer(&status, &out_buffer, xi->rx_buffer_pool, pi->first_buffer, 0, pi->total_length);
   8.224 -    if (status != STATUS_SUCCESS)
   8.225 -    {
   8.226 -      KdPrint((__DRIVER_NAME "     No free rx buffers\n"));
   8.227 -      put_packet_on_freelist(xi, packet);
   8.228 -      return NULL;
   8.229 -    } 
   8.230 -    NdisChainBufferAtBack(packet, out_buffer);
   8.231 -    *(shared_buffer_t **)&packet->MiniportReservedEx[0] = pi->first_pb;
   8.232 -    ref_pb(xi, pi->first_pb); /* so that the buffer doesn't get freed at the end of MakePackets*/
   8.233 -    //FUNCTION_EXIT();
   8.234 -    /* windows gets lazy about ack packets and holds on to them forever under high load situations. we don't like this */
   8.235 -    if (pi->ip_proto == 6 && pi->total_length <= NDIS_STATUS_RESOURCES_MAX_LENGTH)
   8.236 -      NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_RESOURCES);
   8.237 -    else
   8.238 -      NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
   8.239 -    return packet;
   8.240 -  }
   8.241 -  
   8.242 -  header_buf = NdisAllocateFromNPagedLookasideList(&xi->rx_lookaside_list);
   8.243 -  if (!header_buf)
   8.244 -  {
   8.245 -    KdPrint((__DRIVER_NAME "     No free header buffers\n"));
   8.246 -    put_packet_on_freelist(xi, packet);
   8.247 -    return NULL;
   8.248 -  }
   8.249 -  header_va = (PUCHAR)(header_buf + 1);
   8.250 -  NdisZeroMemory(header_buf, sizeof(shared_buffer_t));
   8.251 -  NdisMoveMemory(header_va, pi->header, pi->header_length);
   8.252 -
   8.253 -  /* make sure we satisfy the lookahead requirement */
   8.254 -  
   8.255 -  if (pi->split_required)
   8.256 -  {
   8.257 -    /* for split packets we need to make sure the 'header' is no bigger than header+mss bytes */
   8.258 -    XenNet_BuildHeader(pi, header_va, min((ULONG)MAX_ETH_HEADER_LENGTH + pi->ip4_header_length + pi->tcp_header_length + pi->mss, MAX_ETH_HEADER_LENGTH + max(MIN_LOOKAHEAD_LENGTH, xi->current_lookahead)));
   8.259 -  }
   8.260 -  else
   8.261 -  {
   8.262 -    XenNet_BuildHeader(pi, header_va, max(MIN_LOOKAHEAD_LENGTH, xi->current_lookahead) + MAX_ETH_HEADER_LENGTH);
   8.263 -  }
   8.264 -  header_extra = pi->header_length - (MAX_ETH_HEADER_LENGTH + pi->ip4_header_length + pi->tcp_header_length);
   8.265 -  ASSERT(pi->header_length <= MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH);
   8.266 -  NdisAllocateBuffer(&status, &out_buffer, xi->rx_buffer_pool, header_va, pi->header_length);
   8.267 -  if (status != STATUS_SUCCESS)
   8.268 -  {
   8.269 -    KdPrint((__DRIVER_NAME "     No free header buffers\n"));
   8.270 -    NdisFreeToNPagedLookasideList(&xi->rx_lookaside_list, header_buf);
   8.271 -    put_packet_on_freelist(xi, packet);
   8.272 -    return NULL;
   8.273 -  }
   8.274 -  NdisChainBufferAtBack(packet, out_buffer);
   8.275 -  packet_length += pi->header_length;
   8.276 -  *(shared_buffer_t **)&packet->MiniportReservedEx[0] = header_buf;
   8.277 -  header_buf->next = pi->curr_pb;
   8.278 -
   8.279 -  // TODO: if there are only a few bytes left on the first buffer then add them to the header buffer too... maybe
   8.280 -
   8.281 -  if (pi->split_required)
   8.282 -  {
   8.283 -    tcp_length = (USHORT)min(pi->mss, pi->tcp_remaining);
   8.284 -    new_ip4_length = (USHORT)(pi->ip4_header_length + pi->tcp_header_length + tcp_length);
   8.285 -    //KdPrint((__DRIVER_NAME "     new_ip4_length = %d\n", new_ip4_length));
   8.286 -    //KdPrint((__DRIVER_NAME "     this tcp_length = %d\n", tcp_length));
   8.287 -    SET_NET_USHORT(&header_va[XN_HDR_SIZE + 2], new_ip4_length);
   8.288 -    SET_NET_ULONG(&header_va[XN_HDR_SIZE + pi->ip4_header_length + 4], pi->tcp_seq);
   8.289 -    pi->tcp_seq += tcp_length;
   8.290 -    pi->tcp_remaining = (USHORT)(pi->tcp_remaining - tcp_length);
   8.291 -    /* part of the packet is already present in the header buffer for lookahead */
   8.292 -    out_remaining = tcp_length - header_extra;
   8.293 -    ASSERT((LONG)out_remaining >= 0);
   8.294 -  }
   8.295 -  else
   8.296 -  {
   8.297 -    out_remaining = pi->total_length - pi->header_length;
   8.298 -    ASSERT((LONG)out_remaining >= 0);
   8.299 -  }
   8.300 -  //KdPrint((__DRIVER_NAME "     before loop - out_remaining = %d\n", out_remaining));
   8.301 -
   8.302 -  while (out_remaining != 0)
   8.303 -  {
   8.304 -    ULONG in_buffer_offset;
   8.305 -    ULONG in_buffer_length;
   8.306 -    ULONG out_length;
   8.307 -    
   8.308 -    //KdPrint((__DRIVER_NAME "     in loop - out_remaining = %d, curr_buffer = %p, curr_pb = %p\n", out_remaining, pi->curr_buffer, pi->curr_pb));
   8.309 -    if (!pi->curr_buffer || !pi->curr_pb)
   8.310 -    {
   8.311 -      KdPrint((__DRIVER_NAME "     out of buffers for packet\n"));
   8.312 -      KdPrint((__DRIVER_NAME "     out_remaining = %d, curr_buffer = %p, curr_pb = %p\n", out_remaining, pi->curr_buffer, pi->curr_pb));
   8.313 -      // TODO: free some stuff or we'll leak
   8.314 -      /* unchain buffers then free packet */
   8.315 -      return NULL;
   8.316 -    }
   8.317 -    NdisQueryBufferOffset(pi->curr_buffer, &in_buffer_offset, &in_buffer_length);
   8.318 -    out_length = min(out_remaining, in_buffer_length - pi->curr_mdl_offset);
   8.319 -    NdisCopyBuffer(&status, &out_buffer, xi->rx_buffer_pool, pi->curr_buffer, pi->curr_mdl_offset, out_length);
   8.320 -    ASSERT(status == STATUS_SUCCESS); //TODO: properly handle error
   8.321 -    NdisChainBufferAtBack(packet, out_buffer);
   8.322 -    packet_length += out_length;
   8.323 -    ref_pb(xi, pi->curr_pb);
   8.324 -    pi->curr_mdl_offset = (USHORT)(pi->curr_mdl_offset + out_length);
   8.325 -    if (pi->curr_mdl_offset == in_buffer_length)
   8.326 -    {
   8.327 -      NdisGetNextBuffer(pi->curr_buffer, &pi->curr_buffer);
   8.328 -      pi->curr_pb = pi->curr_pb->next;
   8.329 -      pi->curr_mdl_offset = 0;
   8.330 -    }
   8.331 -    out_remaining -= out_length;
   8.332 -  }
   8.333 -  if (pi->split_required) {
   8.334 -    XenNet_SumIpHeader(header_va, pi->ip4_header_length);
   8.335 -  }
   8.336 -  if (header_extra > 0)
   8.337 -    pi->header_length -= header_extra;
   8.338 -  ASSERT(*(shared_buffer_t **)&packet->MiniportReservedEx[0]);
   8.339 -  /* windows gets lazy about ack packets and holds on to them forever under high load situations. we don't like this */
   8.340 -  if (pi->ip_proto == 6 && packet_length <= NDIS_STATUS_RESOURCES_MAX_LENGTH)
   8.341 -    NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_RESOURCES);
   8.342 -  else
   8.343 -    NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
   8.344 -  //FUNCTION_EXIT();
   8.345 -  return packet;
   8.346 -}
   8.347 -
   8.348 -/*
   8.349 - Windows appears to insist that the checksum on received packets is correct, and won't
   8.350 - believe us when we lie about it, which happens when the packet is generated on the
   8.351 - same bridge in Dom0. Doh!
   8.352 - This is only for TCP and UDP packets. IP checksums appear to be correct anyways.
   8.353 -*/
   8.354 -
   8.355 -static BOOLEAN
   8.356 -XenNet_SumPacketData(
   8.357 -  packet_info_t *pi,
   8.358 -  PNDIS_PACKET packet,
   8.359 -  BOOLEAN set_csum
   8.360 -)
   8.361 -{
   8.362 -  USHORT i;
   8.363 -  PUCHAR buffer;
   8.364 -  PMDL mdl;
   8.365 -  UINT total_length;
   8.366 -  UINT data_length;
   8.367 -  UINT buffer_length;
   8.368 -  USHORT buffer_offset;
   8.369 -  ULONG csum;
   8.370 -  PUSHORT csum_ptr;
   8.371 -  USHORT remaining;
   8.372 -  USHORT ip4_length;
   8.373 -  BOOLEAN csum_span = TRUE; /* when the USHORT to be checksummed spans a buffer */
   8.374 -  
   8.375 -  //FUNCTION_ENTER();
   8.376 -
   8.377 -  NdisGetFirstBufferFromPacketSafe(packet, &mdl, &buffer, &buffer_length, &total_length, NormalPagePriority);
   8.378 -  if (!buffer) {
   8.379 -    FUNCTION_MSG("NdisGetFirstBufferFromPacketSafe failed, buffer == NULL\n");
   8.380 -    return FALSE;
   8.381 -  }
   8.382 -  ASSERT(mdl);
   8.383 -
   8.384 -  ip4_length = GET_NET_PUSHORT(&buffer[XN_HDR_SIZE + 2]);
   8.385 -  data_length = ip4_length + XN_HDR_SIZE;
   8.386 -  
   8.387 -  if ((USHORT)data_length > total_length) {
   8.388 -    FUNCTION_MSG("Size Mismatch %d (ip4_length + XN_HDR_SIZE) != %d (total_length)\n", ip4_length + XN_HDR_SIZE, total_length);
   8.389 -    return FALSE;
   8.390 -  }
   8.391 -
   8.392 -  switch (pi->ip_proto)
   8.393 -  {
   8.394 -  case 6:
   8.395 -    ASSERT(buffer_length >= (USHORT)(XN_HDR_SIZE + pi->ip4_header_length + 17));
   8.396 -    csum_ptr = (USHORT *)&buffer[XN_HDR_SIZE + pi->ip4_header_length + 16];
   8.397 -    break;
   8.398 -  case 17:
   8.399 -    ASSERT(buffer_length >= (USHORT)(XN_HDR_SIZE + pi->ip4_header_length + 7));
   8.400 -    csum_ptr = (USHORT *)&buffer[XN_HDR_SIZE + pi->ip4_header_length + 6];
   8.401 -    break;
   8.402 -  default:
   8.403 -    KdPrint((__DRIVER_NAME "     Don't know how to calc sum for IP Proto %d\n", pi->ip_proto));
   8.404 -    //FUNCTION_EXIT();
   8.405 -    return FALSE; // should never happen
   8.406 -  }
   8.407 -
   8.408 -  if (set_csum)  
   8.409 -    *csum_ptr = 0;
   8.410 -
   8.411 -  csum = 0;
   8.412 -  csum += GET_NET_PUSHORT(&buffer[XN_HDR_SIZE + 12]) + GET_NET_PUSHORT(&buffer[XN_HDR_SIZE + 14]); // src
   8.413 -  csum += GET_NET_PUSHORT(&buffer[XN_HDR_SIZE + 16]) + GET_NET_PUSHORT(&buffer[XN_HDR_SIZE + 18]); // dst
   8.414 -  csum += ((USHORT)buffer[XN_HDR_SIZE + 9]);
   8.415 -
   8.416 -  remaining = ip4_length - pi->ip4_header_length;
   8.417 -
   8.418 -  csum += remaining;
   8.419 -  
   8.420 -  csum_span = FALSE;
   8.421 -  buffer_offset = i = XN_HDR_SIZE + pi->ip4_header_length;
   8.422 -  while (i < data_length)
   8.423 -  {
   8.424 -    /* don't include the checksum field itself in the calculation */
   8.425 -    if ((pi->ip_proto == 6 && i == XN_HDR_SIZE + pi->ip4_header_length + 16) || (pi->ip_proto == 17 && i == XN_HDR_SIZE + pi->ip4_header_length + 6))
   8.426 -    {
   8.427 -      /* we know that this always happens in the header buffer so we are guaranteed the full two bytes */
   8.428 -      i += 2;
   8.429 -      buffer_offset += 2;
   8.430 -      continue;
   8.431 -    }
   8.432 -    if (csum_span)
   8.433 -    {
   8.434 -      /* the other half of the next bit */
   8.435 -      ASSERT(buffer_offset == 0);
   8.436 -      csum += (USHORT)buffer[buffer_offset];
   8.437 -      csum_span = FALSE;
   8.438 -      i += 1;
   8.439 -      buffer_offset += 1;
   8.440 -    }
   8.441 -    else if (buffer_offset == buffer_length - 1)
   8.442 -    {
   8.443 -      /* deal with a buffer ending on an odd byte boundary */
   8.444 -      csum += (USHORT)buffer[buffer_offset] << 8;
   8.445 -      csum_span = TRUE;
   8.446 -      i += 1;
   8.447 -      buffer_offset += 1;
   8.448 -    }
   8.449 -    else
   8.450 -    {
   8.451 -      csum += GET_NET_PUSHORT(&buffer[buffer_offset]);
   8.452 -      i += 2;
   8.453 -      buffer_offset += 2;
   8.454 -    }
   8.455 -    if (buffer_offset == buffer_length && i < total_length)
   8.456 -    {
   8.457 -      NdisGetNextBuffer(mdl, &mdl);
   8.458 -      if (mdl == NULL)
   8.459 -      {
   8.460 -        KdPrint((__DRIVER_NAME "     Ran out of buffers\n"));
   8.461 -        return FALSE; // should never happen
   8.462 -      }
   8.463 -      NdisQueryBufferSafe(mdl, &buffer, &buffer_length, NormalPagePriority);
   8.464 -      ASSERT(buffer_length);
   8.465 -      buffer_offset = 0;
   8.466 -    }
   8.467 -  }
   8.468 -      
   8.469 -  while (csum & 0xFFFF0000)
   8.470 -    csum = (csum & 0xFFFF) + (csum >> 16);
   8.471 -  
   8.472 -  if (set_csum)
   8.473 -  {
   8.474 -    *csum_ptr = (USHORT)~GET_NET_USHORT((USHORT)csum);
   8.475 -  }
   8.476 -  else
   8.477 -  {
   8.478 -    //FUNCTION_EXIT();
   8.479 -    return (BOOLEAN)(*csum_ptr == (USHORT)~GET_NET_USHORT((USHORT)csum));
   8.480 -  }
   8.481 -  //FUNCTION_EXIT();
   8.482 -  return TRUE;
   8.483 -}
   8.484 -
   8.485 -static ULONG
   8.486 -XenNet_MakePackets(
   8.487 -  struct xennet_info *xi,
   8.488 -  PLIST_ENTRY rx_packet_list,
   8.489 -  packet_info_t *pi
   8.490 -)
   8.491 -{
   8.492 -  ULONG packet_count = 0;
   8.493 -  PNDIS_PACKET packet;
   8.494 -  PLIST_ENTRY entry;
   8.495 -  UCHAR psh;
   8.496 -  PNDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
   8.497 -  ULONG parse_result;  
   8.498 -  //PNDIS_BUFFER buffer;
   8.499 -  shared_buffer_t *page_buf;
   8.500 -
   8.501 -  //FUNCTION_ENTER();
   8.502 -
   8.503 -  parse_result = XenNet_ParsePacketHeader(pi, NULL, 0);
   8.504 -  
   8.505 -  if (!XenNet_FilterAcceptPacket(xi, pi))
   8.506 -  {
   8.507 -    goto done;
   8.508 -  }
   8.509 -
   8.510 -  switch (pi->ip_proto)
   8.511 -  {
   8.512 -  case 6:  // TCP
   8.513 -    if (pi->split_required)
   8.514 -      break;
   8.515 -    // fallthrough
   8.516 -  case 17:  // UDP
   8.517 -    packet = XenNet_MakePacket(xi, pi);
   8.518 -    if (packet == NULL)
   8.519 -    {
   8.520 -      //KdPrint((__DRIVER_NAME "     Ran out of packets\n"));
   8.521 -      xi->stat_rx_no_buffer++;
   8.522 -      packet_count = 0;
   8.523 -      goto done;
   8.524 -    }
   8.525 -    if (parse_result == PARSE_OK)
   8.526 -    {
   8.527 -      BOOLEAN checksum_offload = FALSE;
   8.528 -      csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
   8.529 -        packet, TcpIpChecksumPacketInfo);
   8.530 -      ASSERT(csum_info->Value == 0);
   8.531 -      if (pi->csum_blank || pi->data_validated)
   8.532 -      {
   8.533 -        /* we know this is IPv4, and we know Linux always validates the IPv4 checksum for us */
   8.534 -        if (xi->setting_csum.V4Receive.IpChecksum)
   8.535 -        {
   8.536 -          if (!pi->ip_has_options || xi->setting_csum.V4Receive.IpOptionsSupported)
   8.537 -          {
   8.538 -            if (XenNet_CheckIpHeader(pi->header, pi->ip4_header_length))
   8.539 -              csum_info->Receive.NdisPacketIpChecksumSucceeded = TRUE;
   8.540 -            else
   8.541 -              csum_info->Receive.NdisPacketIpChecksumFailed = TRUE;
   8.542 -          }
   8.543 -        }
   8.544 -        if (xi->setting_csum.V4Receive.TcpChecksum && pi->ip_proto == 6)
   8.545 -        {
   8.546 -          if (!pi->tcp_has_options || xi->setting_csum.V4Receive.TcpOptionsSupported)
   8.547 -          {
   8.548 -            csum_info->Receive.NdisPacketTcpChecksumSucceeded = TRUE;
   8.549 -            checksum_offload = TRUE;
   8.550 -          }
   8.551 -        }
   8.552 -        else if (xi->setting_csum.V4Receive.UdpChecksum && pi->ip_proto == 17)
   8.553 -        {
   8.554 -          csum_info->Receive.NdisPacketUdpChecksumSucceeded = TRUE;
   8.555 -          checksum_offload = TRUE;
   8.556 -        }
   8.557 -        if (pi->csum_blank && (!xi->config_csum_rx_dont_fix || !checksum_offload))
   8.558 -        {
   8.559 -          XenNet_SumPacketData(pi, packet, TRUE);
   8.560 -        }
   8.561 -      }
   8.562 -      else if (xi->config_csum_rx_check && pi->ip_version == 4)
   8.563 -      {
   8.564 -        if (xi->setting_csum.V4Receive.IpChecksum)
   8.565 -        {
   8.566 -          if (!pi->ip_has_options || xi->setting_csum.V4Receive.IpOptionsSupported)
   8.567 -          {
   8.568 -            if (XenNet_CheckIpHeader(pi->header, pi->ip4_header_length))
   8.569 -              csum_info->Receive.NdisPacketIpChecksumSucceeded = TRUE;
   8.570 -            else
   8.571 -              csum_info->Receive.NdisPacketIpChecksumFailed = TRUE;
   8.572 -          }
   8.573 -        }
   8.574 -        if (xi->setting_csum.V4Receive.TcpChecksum && pi->ip_proto == 6)
   8.575 -        {
   8.576 -          if (!pi->tcp_has_options || xi->setting_csum.V4Receive.TcpOptionsSupported)
   8.577 -          {
   8.578 -            if (XenNet_SumPacketData(pi, packet, FALSE))
   8.579 -            {
   8.580 -              csum_info->Receive.NdisPacketTcpChecksumSucceeded = TRUE;
   8.581 -            }
   8.582 -            else
   8.583 -            {
   8.584 -              csum_info->Receive.NdisPacketTcpChecksumFailed = TRUE;
   8.585 -            }
   8.586 -          }
   8.587 -        }
   8.588 -        else if (xi->setting_csum.V4Receive.UdpChecksum && pi->ip_proto == 17)
   8.589 -        {
   8.590 -          if (XenNet_SumPacketData(pi, packet, FALSE))
   8.591 -          {
   8.592 -            csum_info->Receive.NdisPacketUdpChecksumSucceeded = TRUE;
   8.593 -          }
   8.594 -          else
   8.595 -          {
   8.596 -            csum_info->Receive.NdisPacketUdpChecksumFailed = TRUE;
   8.597 -          }
   8.598 -        }
   8.599 -      }
   8.600 -    }
   8.601 -    entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
   8.602 -    InsertTailList(rx_packet_list, entry);
   8.603 -    packet_count = 1;
   8.604 -    goto done;
   8.605 -  default:
   8.606 -    packet = XenNet_MakePacket(xi, pi);
   8.607 -    if (packet == NULL)
   8.608 -    {
   8.609 -      //KdPrint((__DRIVER_NAME "     Ran out of packets\n"));
   8.610 -      xi->stat_rx_no_buffer++;
   8.611 -      packet_count = 0;
   8.612 -      goto done;
   8.613 -    }
   8.614 -    entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
   8.615 -    InsertTailList(rx_packet_list, entry);
   8.616 -    packet_count = 1;
   8.617 -    goto done;
   8.618 -  }
   8.619 -  
   8.620 -  pi->tcp_remaining = pi->tcp_length;
   8.621 -
   8.622 -  /* we can make certain assumptions here as the following code is only for tcp4 */
   8.623 -  psh = pi->header[XN_HDR_SIZE + pi->ip4_header_length + 13] & 8;
   8.624 -  while (pi->tcp_remaining)
   8.625 -  {
   8.626 -    PUCHAR header_va;
   8.627 -    PMDL mdl;
   8.628 -    UINT total_length;
   8.629 -    UINT buffer_length;
   8.630 -    packet = XenNet_MakePacket(xi, pi);
   8.631 -    if (!packet)
   8.632 -    {
   8.633 -      //KdPrint((__DRIVER_NAME "     Ran out of packets\n"));
   8.634 -      xi->stat_rx_no_buffer++;
   8.635 -      break; /* we are out of memory - just drop the packets */
   8.636 -    }
   8.637 -    if (xi->setting_csum.V4Receive.TcpChecksum)
   8.638 -    {
   8.639 -      csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
   8.640 -        packet, TcpIpChecksumPacketInfo);
   8.641 -      csum_info->Receive.NdisPacketIpChecksumSucceeded = TRUE;
   8.642 -      csum_info->Receive.NdisPacketTcpChecksumSucceeded = TRUE;
   8.643 -    }
   8.644 -    if (psh)
   8.645 -    {
   8.646 -      NdisGetFirstBufferFromPacketSafe(packet, &mdl, &header_va, &buffer_length, &total_length, NormalPagePriority);
   8.647 -      if (pi->tcp_remaining)
   8.648 -        header_va[XN_HDR_SIZE + pi->ip4_header_length + 13] &= ~8;
   8.649 -      else
   8.650 -        header_va[XN_HDR_SIZE + pi->ip4_header_length + 13] |= 8;
   8.651 -    }
   8.652 -    XenNet_SumPacketData(pi, packet, TRUE);
   8.653 -    entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
   8.654 -    InsertTailList(rx_packet_list, entry);
   8.655 -    packet_count++;
   8.656 -  }
   8.657 -
   8.658 -done:
   8.659 -  page_buf = pi->first_pb;
   8.660 -  while (page_buf)
   8.661 -  {
   8.662 -    shared_buffer_t *next_pb;
   8.663 -
   8.664 -    next_pb = page_buf->next;
   8.665 -    put_pb_on_freelist(xi, page_buf);
   8.666 -    page_buf = next_pb;
   8.667 -  }
   8.668 -  XenNet_ClearPacketInfo(pi);
   8.669 -  //FUNCTION_EXIT();
   8.670 -  return packet_count;
   8.671 -}
   8.672 -
   8.673 -
   8.674 -/* called at DISPATCH_LEVEL */
   8.675 -/* it's okay for return packet to be called while resume_state != RUNNING as the packet will simply be added back to the freelist, the grants will be fixed later */
   8.676 -VOID
   8.677 -XenNet_ReturnPacket(
   8.678 -  IN NDIS_HANDLE MiniportAdapterContext,
   8.679 -  IN PNDIS_PACKET Packet
   8.680 -  )
   8.681 -{
   8.682 -  struct xennet_info *xi = MiniportAdapterContext;
   8.683 -  PNDIS_BUFFER buffer;
   8.684 -  shared_buffer_t *page_buf = *(shared_buffer_t **)&Packet->MiniportReservedEx[0];
   8.685 -
   8.686 -  //FUNCTION_ENTER();
   8.687 -
   8.688 -  //KdPrint((__DRIVER_NAME "     page_buf = %p\n", page_buf));
   8.689 -
   8.690 -  NdisUnchainBufferAtFront(Packet, &buffer);
   8.691 -  
   8.692 -  while (buffer)
   8.693 -  {
   8.694 -    shared_buffer_t *next_buf;
   8.695 -    ASSERT(page_buf);
   8.696 -    next_buf = page_buf->next;
   8.697 -    if (!page_buf->virtual)
   8.698 -    {
   8.699 -      /* this isn't actually a share_buffer, it is some memory allocated for the header - just free it */
   8.700 -      PUCHAR va;
   8.701 -      UINT len;
   8.702 -      #pragma warning(suppress:28193) /* va is valid because it was mapped earlier */
   8.703 -      NdisQueryBufferSafe(buffer, &va, &len, NormalPagePriority);
   8.704 -      NdisFreeToNPagedLookasideList(&xi->rx_lookaside_list, va - sizeof(shared_buffer_t));
   8.705 -      NdisFreeBuffer(buffer);
   8.706 -    }
   8.707 -    else
   8.708 -    {
   8.709 -      //KdPrint((__DRIVER_NAME "     returning page_buf %p with id %d\n", page_buf, page_buf->id));
   8.710 -      if (buffer != page_buf->buffer)
   8.711 -        NdisFreeBuffer(buffer);
   8.712 -      put_pb_on_freelist(xi, page_buf);
   8.713 -    }
   8.714 -    NdisUnchainBufferAtFront(Packet, &buffer);
   8.715 -    page_buf = next_buf;
   8.716 -  }
   8.717 -
   8.718 -  put_packet_on_freelist(xi, Packet);
   8.719 -  if (!InterlockedDecrement(&xi->rx_outstanding)) {
   8.720 -    if (xi->rx_shutting_down) {
   8.721 -      KeSetEvent(&xi->packet_returned_event, IO_NO_INCREMENT, FALSE);
   8.722 -    } else {
   8.723 -      /* check performance of this - only happens on ring empty */
   8.724 -      KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
   8.725 -      XenNet_FillRing(xi);
   8.726 -      KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
   8.727 -    }
   8.728 -  }
   8.729 -  //FUNCTION_EXIT();
   8.730 -}
   8.731 -  
   8.732 -#define MAXIMUM_PACKETS_PER_INDICATE 32
   8.733 -
   8.734 -/* We limit the number of packets per interrupt so that acks get a chance
   8.735 -under high rx load. The DPC is immediately re-scheduled */
   8.736 -#define MAXIMUM_PACKETS_PER_INTERRUPT 32 /* this is calculated before large packet split */
   8.737 -#define MAXIMUM_DATA_PER_INTERRUPT (MAXIMUM_PACKETS_PER_INTERRUPT * 1500) /* help account for large packets */
   8.738 -
   8.739 -// Called at DISPATCH_LEVEL
   8.740 -BOOLEAN
   8.741 -XenNet_RxBufferCheck(struct xennet_info *xi)
   8.742 -{
   8.743 -  RING_IDX cons, prod;
   8.744 -  LIST_ENTRY rx_packet_list;
   8.745 -  LIST_ENTRY rx_header_only_packet_list;
   8.746 -  PLIST_ENTRY entry;
   8.747 -  PNDIS_PACKET packets[MAXIMUM_PACKETS_PER_INDICATE];
   8.748 -  ULONG packet_count = 0;
   8.749 -  ULONG buffer_count = 0;
   8.750 -  ULONG packet_data = 0;
   8.751 -  ULONG interim_packet_data = 0;
   8.752 -  struct netif_extra_info *ei;
   8.753 -  USHORT id;
   8.754 -  int more_to_do = FALSE;
   8.755 -  packet_info_t *pi = &xi->rxpi[KeGetCurrentProcessorNumber() & 0xff];
   8.756 -  shared_buffer_t *page_buf;
   8.757 -  shared_buffer_t *head_buf = NULL;
   8.758 -  shared_buffer_t *tail_buf = NULL;
   8.759 -  shared_buffer_t *last_buf = NULL;
   8.760 -  BOOLEAN extra_info_flag = FALSE;
   8.761 -  BOOLEAN more_data_flag = FALSE;
   8.762 -  PNDIS_BUFFER buffer;
   8.763 -  BOOLEAN dont_set_event;
   8.764 -
   8.765 -  //FUNCTION_ENTER();
   8.766 -
   8.767 -  if (!xi->connected)
   8.768 -    return FALSE; /* a delayed DPC could let this come through... just do nothing */
   8.769 -
   8.770 -  InitializeListHead(&rx_packet_list);
   8.771 -
   8.772 -  /* get all the buffers off the ring as quickly as possible so the lock is held for a minimum amount of time */
   8.773 -
   8.774 -  KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
   8.775 -  
   8.776 -  if (xi->rx_shutting_down)
   8.777 -  {
   8.778 -    /* there is a chance that our Dpc had been queued just before the shutdown... */
   8.779 -    KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
   8.780 -    return FALSE;
   8.781 -  }
   8.782 -
   8.783 -  if (xi->rx_partial_buf)
   8.784 -  {
   8.785 -    head_buf = xi->rx_partial_buf;
   8.786 -    tail_buf = xi->rx_partial_buf;
   8.787 -    while (tail_buf->next)
   8.788 -      tail_buf = tail_buf->next;
   8.789 -    more_data_flag = xi->rx_partial_more_data_flag;
   8.790 -    extra_info_flag = xi->rx_partial_extra_info_flag;
   8.791 -    xi->rx_partial_buf = NULL;
   8.792 -  }
   8.793 -
   8.794 -  do {
   8.795 -    prod = xi->rx.sring->rsp_prod;
   8.796 -    KeMemoryBarrier(); /* Ensure we see responses up to 'prod'. */
   8.797 -
   8.798 -    for (cons = xi->rx.rsp_cons; cons != prod && packet_count < MAXIMUM_PACKETS_PER_INTERRUPT && packet_data < MAXIMUM_DATA_PER_INTERRUPT; cons++)
   8.799 -    {
   8.800 -      id = (USHORT)(cons & (NET_RX_RING_SIZE - 1));
   8.801 -      page_buf = xi->rx_ring_pbs[id];
   8.802 -      ASSERT(page_buf);
   8.803 -      xi->rx_ring_pbs[id] = NULL;
   8.804 -      xi->rx_id_free++;
   8.805 -      memcpy(&page_buf->rsp, RING_GET_RESPONSE(&xi->rx, cons), max(sizeof(struct netif_rx_response), sizeof(struct netif_extra_info)));
   8.806 -      if (!extra_info_flag)
   8.807 -      {
   8.808 -        if (page_buf->rsp.status <= 0
   8.809 -          || page_buf->rsp.offset + page_buf->rsp.status > PAGE_SIZE)
   8.810 -        {
   8.811 -          KdPrint((__DRIVER_NAME "     Error: rsp offset %d, size %d\n",
   8.812 -            page_buf->rsp.offset, page_buf->rsp.status));
   8.813 -          ASSERT(!extra_info_flag);
   8.814 -          put_pb_on_freelist(xi, page_buf);
   8.815 -          continue;
   8.816 -        }
   8.817 -      }
   8.818 -      
   8.819 -      if (!head_buf)
   8.820 -      {
   8.821 -        head_buf = page_buf;
   8.822 -        tail_buf = page_buf;
   8.823 -      }
   8.824 -      else
   8.825 -      {
   8.826 -        tail_buf->next = page_buf;
   8.827 -        tail_buf = page_buf;
   8.828 -      }
   8.829 -      page_buf->next = NULL;
   8.830 -
   8.831 -      if (extra_info_flag)
   8.832 -      {
   8.833 -        ei = (struct netif_extra_info *)&page_buf->rsp;
   8.834 -        extra_info_flag = ei->flags & XEN_NETIF_EXTRA_FLAG_MORE;
   8.835 -      }
   8.836 -      else
   8.837 -      {
   8.838 -        more_data_flag = (BOOLEAN)(page_buf->rsp.flags & NETRXF_more_data);
   8.839 -        extra_info_flag = (BOOLEAN)(page_buf->rsp.flags & NETRXF_extra_info);
   8.840 -        interim_packet_data += page_buf->rsp.status;
   8.841 -      }
   8.842 -      
   8.843 -      if (!extra_info_flag && !more_data_flag)
   8.844 -      {
   8.845 -        last_buf = page_buf;
   8.846 -        packet_count++;
   8.847 -        packet_data += interim_packet_data;
   8.848 -        interim_packet_data = 0;
   8.849 -      }
   8.850 -      buffer_count++;
   8.851 -    }
   8.852 -    xi->rx.rsp_cons = cons;
   8.853 -
   8.854 -    /* Give netback more buffers */
   8.855 -    XenNet_FillRing(xi);
   8.856 -
   8.857 -    if (packet_count >= MAXIMUM_PACKETS_PER_INTERRUPT || packet_data >= MAXIMUM_DATA_PER_INTERRUPT)
   8.858 -      break;
   8.859 -
   8.860 -    more_to_do = RING_HAS_UNCONSUMED_RESPONSES(&xi->rx);
   8.861 -    if (!more_to_do)
   8.862 -    {
   8.863 -      xi->rx.sring->rsp_event = xi->rx.rsp_cons + 1;
   8.864 -      KeMemoryBarrier();
   8.865 -      more_to_do = RING_HAS_UNCONSUMED_RESPONSES(&xi->rx);
   8.866 -    }
   8.867 -  } while (more_to_do);
   8.868 -  
   8.869 -  /* anything past last_buf belongs to an incomplete packet... */
   8.870 -  if (last_buf && last_buf->next)
   8.871 -  {
   8.872 -    KdPrint((__DRIVER_NAME "     Partial receive\n"));
   8.873 -    xi->rx_partial_buf = last_buf->next;
   8.874 -    xi->rx_partial_more_data_flag = more_data_flag;
   8.875 -    xi->rx_partial_extra_info_flag = extra_info_flag;
   8.876 -    last_buf->next = NULL;
   8.877 -  }
   8.878 -
   8.879 -  KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
   8.880 -
   8.881 -  if (packet_count >= MAXIMUM_PACKETS_PER_INTERRUPT || packet_data >= MAXIMUM_DATA_PER_INTERRUPT)
   8.882 -  {
   8.883 -    /* fire again immediately */
   8.884 -    /* we want the Dpc on the end of the queue. By definition we are already on the right CPU so we know the Dpc queue will be run immediately */
   8.885 -    KeSetImportanceDpc(&xi->rxtx_dpc, MediumImportance);
   8.886 -    KeInsertQueueDpc(&xi->rxtx_dpc, NULL, NULL);
   8.887 -    /* dont set an event in TX path */
   8.888 -    dont_set_event = TRUE;
   8.889 -  }
   8.890 -  else
   8.891 -  {
   8.892 -    /* make sure the Dpc queue is run immediately next interrupt */
   8.893 -    KeSetImportanceDpc(&xi->rxtx_dpc, HighImportance);
   8.894 -    /* set an event in TX path */
   8.895 -    dont_set_event = FALSE;
   8.896 -  }
   8.897 -
   8.898 -  /* make packets out of the buffers */
   8.899 -  page_buf = head_buf;
   8.900 -  extra_info_flag = FALSE;
   8.901 -  more_data_flag = FALSE;
   8.902 -  while (page_buf)
   8.903 -  {
   8.904 -    shared_buffer_t *next_buf = page_buf->next;
   8.905 -
   8.906 -    page_buf->next = NULL;
   8.907 -    if (extra_info_flag)
   8.908 -    {
   8.909 -      //KdPrint((__DRIVER_NAME "     processing extra info\n"));
   8.910 -      ei = (struct netif_extra_info *)&page_buf->rsp;
   8.911 -      extra_info_flag = ei->flags & XEN_NETIF_EXTRA_FLAG_MORE;
   8.912 -      switch (ei->type)
   8.913 -      {
   8.914 -      case XEN_NETIF_EXTRA_TYPE_GSO:
   8.915 -        switch (ei->u.gso.type)
   8.916 -        {
   8.917 -        case XEN_NETIF_GSO_TYPE_TCPV4:
   8.918 -          pi->mss = ei->u.gso.size;
   8.919 -          //KdPrint((__DRIVER_NAME "     mss = %d\n", pi->mss));
   8.920 -          // TODO - put this assertion somewhere ASSERT(header_len + pi->mss <= PAGE_SIZE); // this limits MTU to PAGE_SIZE - XN_HEADER_LEN
   8.921 -          break;
   8.922 -        default:
   8.923 -          KdPrint((__DRIVER_NAME "     Unknown GSO type (%d) detected\n", ei->u.gso.type));
   8.924 -          break;
   8.925 -        }
   8.926 -        break;
   8.927 -      default:
   8.928 -        KdPrint((__DRIVER_NAME "     Unknown extra info type (%d) detected\n", ei->type));
   8.929 -        break;
   8.930 -      }
   8.931 -      put_pb_on_freelist(xi, page_buf);
   8.932 -    }
   8.933 -    else
   8.934 -    {
   8.935 -      ASSERT(!page_buf->rsp.offset);
   8.936 -      if (!more_data_flag) // handling the packet's 1st buffer
   8.937 -      {
   8.938 -        if (page_buf->rsp.flags & NETRXF_csum_blank)
   8.939 -          pi->csum_blank = TRUE;
   8.940 -        if (page_buf->rsp.flags & NETRXF_data_validated)
   8.941 -          pi->data_validated = TRUE;
   8.942 -      }
   8.943 -      buffer = page_buf->buffer;
   8.944 -      NdisAdjustBufferLength(buffer, page_buf->rsp.status);
   8.945 -      //KdPrint((__DRIVER_NAME "     buffer = %p, pb = %p\n", buffer, page_buf));
   8.946 -      if (pi->first_pb)
   8.947 -      {
   8.948 -        ASSERT(pi->curr_pb);
   8.949 -        //KdPrint((__DRIVER_NAME "     additional buffer\n"));
   8.950 -        pi->curr_pb->next = page_buf;
   8.951 -        pi->curr_pb = page_buf;
   8.952 -        ASSERT(pi->curr_buffer);
   8.953 -        NDIS_BUFFER_LINKAGE(pi->curr_buffer) = buffer;
   8.954 -        pi->curr_buffer = buffer;
   8.955 -      }
   8.956 -      else
   8.957 -      {
   8.958 -        pi->first_pb = page_buf;
   8.959 -        pi->curr_pb = page_buf;
   8.960 -        pi->first_buffer = buffer;
   8.961 -        pi->curr_buffer = buffer;
   8.962 -      }
   8.963 -      pi->mdl_count++;
   8.964 -      extra_info_flag = (BOOLEAN)(page_buf->rsp.flags & NETRXF_extra_info);
   8.965 -      more_data_flag = (BOOLEAN)(page_buf->rsp.flags & NETRXF_more_data);
   8.966 -      pi->total_length = pi->total_length + page_buf->rsp.status;
   8.967 -    }
   8.968 -
   8.969 -    /* Packet done, add it to the list */
   8.970 -    if (!more_data_flag && !extra_info_flag)
   8.971 -    {
   8.972 -      pi->curr_pb = pi->first_pb;
   8.973 -      pi->curr_buffer = pi->first_buffer;
   8.974 -      XenNet_MakePackets(xi, &rx_packet_list, pi);
   8.975 -    }
   8.976 -
   8.977 -    page_buf = next_buf;
   8.978 -  }
   8.979 -  ASSERT(!more_data_flag && !extra_info_flag);
   8.980 -      
   8.981 -  xi->stat_rx_ok += packet_count;
   8.982 -
   8.983 -  /* indicate packets to NDIS */
   8.984 -  entry = RemoveHeadList(&rx_packet_list);
   8.985 -  InitializeListHead(&rx_header_only_packet_list);
   8.986 -  packet_count = 0;
   8.987 -
   8.988 -  while (entry != &rx_packet_list) {
   8.989 -    PNDIS_PACKET packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
   8.990 -    NDIS_STATUS status;
   8.991 -    ASSERT(*(shared_buffer_t **)&packet->MiniportReservedEx[0]);
   8.992 -    status = NDIS_GET_PACKET_STATUS(packet);
   8.993 -    if (status == NDIS_STATUS_RESOURCES)
   8.994 -      InsertTailList(&rx_header_only_packet_list, entry);
   8.995 -    packets[packet_count++] = packet;
   8.996 -    InterlockedIncrement(&xi->rx_outstanding);
   8.997 -    entry = RemoveHeadList(&rx_packet_list);
   8.998 -    /* if we indicate a packet with NDIS_STATUS_RESOURCES then any following packet can't be NDIS_STATUS_SUCCESS */
   8.999 -    if (packet_count == MAXIMUM_PACKETS_PER_INDICATE || entry == &rx_packet_list
  8.1000 -        || (NDIS_GET_PACKET_STATUS(CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)])) == NDIS_STATUS_SUCCESS
  8.1001 -            && status == NDIS_STATUS_RESOURCES))
  8.1002 -    {
  8.1003 -      NdisMIndicateReceivePacket(xi->adapter_handle, packets, packet_count);
  8.1004 -      packet_count = 0;
  8.1005 -    }
  8.1006 -  }
  8.1007 -  /* now return the packets for which we indicated NDIS_STATUS_RESOURCES */
  8.1008 -  entry = RemoveHeadList(&rx_header_only_packet_list);
  8.1009 -  while (entry != &rx_header_only_packet_list) {
  8.1010 -    PNDIS_PACKET packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
  8.1011 -    entry = RemoveHeadList(&rx_header_only_packet_list);
  8.1012 -    XenNet_ReturnPacket(xi, packet);
  8.1013 -  }
  8.1014 -
  8.1015 -  return dont_set_event;
  8.1016 -  //FUNCTION_EXIT();
  8.1017 -}
  8.1018 -
  8.1019 -/*
  8.1020 -   Free all Rx buffers (on halt, for example) 
  8.1021 -   The ring must be stopped at this point.
  8.1022 -*/
  8.1023 -
  8.1024 -static VOID
  8.1025 -XenNet_PurgeRing(struct xennet_info *xi)
  8.1026 -{
  8.1027 -  int i;
  8.1028 -  for (i = 0; i < NET_RX_RING_SIZE; i++)
  8.1029 -  {
  8.1030 -    if (xi->rx_ring_pbs[i] != NULL)
  8.1031 -    {
  8.1032 -      put_pb_on_freelist(xi, xi->rx_ring_pbs[i]);
  8.1033 -      xi->rx_ring_pbs[i] = NULL;
  8.1034 -    }
  8.1035 -  }
  8.1036 -}
  8.1037 -
  8.1038 -static VOID
  8.1039 -XenNet_BufferFree(struct xennet_info *xi)
  8.1040 -{
  8.1041 -  shared_buffer_t *pb;
  8.1042 -
  8.1043 -  XenNet_PurgeRing(xi);
  8.1044 -
  8.1045 -  while ((pb = get_pb_from_freelist(xi)) != NULL)
  8.1046 -  {
  8.1047 -    NdisFreeBuffer(pb->buffer);
  8.1048 -    xi->vectors.GntTbl_EndAccess(xi->vectors.context,
  8.1049 -        pb->gref, FALSE, (ULONG)'XNRX');
  8.1050 -    NdisFreeMemory(pb->virtual, PAGE_SIZE, 0);
  8.1051 -    NdisFreeMemory(pb, sizeof(shared_buffer_t), 0);
  8.1052 -  }
  8.1053 -}
  8.1054 -
  8.1055 -VOID
  8.1056 -XenNet_RxResumeStart(xennet_info_t *xi)
  8.1057 -{
  8.1058 -  KIRQL old_irql;
  8.1059 -
  8.1060 -  FUNCTION_ENTER();
  8.1061 -
  8.1062 -  KeAcquireSpinLock(&xi->rx_lock, &old_irql);
  8.1063 -  XenNet_PurgeRing(xi);
  8.1064 -  KeReleaseSpinLock(&xi->rx_lock, old_irql);
  8.1065 -  
  8.1066 -  FUNCTION_EXIT();
  8.1067 -}
  8.1068 -
  8.1069 -VOID
  8.1070 -XenNet_BufferAlloc(xennet_info_t *xi)
  8.1071 -{
  8.1072 -  //NDIS_STATUS status;
  8.1073 -  int i;
  8.1074 -  
  8.1075 -  xi->rx_id_free = NET_RX_RING_SIZE;
  8.1076 -  xi->rx_outstanding = 0;
  8.1077 -
  8.1078 -  for (i = 0; i < NET_RX_RING_SIZE; i++)
  8.1079 -  {
  8.1080 -    xi->rx_ring_pbs[i] = NULL;
  8.1081 -  }
  8.1082 -}
  8.1083 -
  8.1084 -VOID
  8.1085 -XenNet_RxResumeEnd(xennet_info_t *xi)
  8.1086 -{
  8.1087 -  KIRQL old_irql;
  8.1088 -
  8.1089 -  FUNCTION_ENTER();
  8.1090 -
  8.1091 -  KeAcquireSpinLock(&xi->rx_lock, &old_irql);
  8.1092 -  //XenNet_BufferAlloc(xi);
  8.1093 -  XenNet_FillRing(xi);
  8.1094 -  KeReleaseSpinLock(&xi->rx_lock, old_irql);
  8.1095 -  
  8.1096 -  FUNCTION_EXIT();
  8.1097 -}
  8.1098 -
  8.1099 -BOOLEAN
  8.1100 -XenNet_RxInit(xennet_info_t *xi)
  8.1101 -{
  8.1102 -  NDIS_STATUS status;
  8.1103 -
  8.1104 -  FUNCTION_ENTER();
  8.1105 -
  8.1106 -  xi->rx_shutting_down = FALSE;
  8.1107 -  KeInitializeSpinLock(&xi->rx_lock);
  8.1108 -  KeInitializeEvent(&xi->packet_returned_event, SynchronizationEvent, FALSE);
  8.1109 -  KeInitializeTimer(&xi->rx_timer);
  8.1110 -  status = NdisAllocateMemoryWithTag((PVOID)&xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount(), XENNET_POOL_TAG);
  8.1111 -  if (status != NDIS_STATUS_SUCCESS)
  8.1112 -  {
  8.1113 -    KdPrint(("NdisAllocateMemoryWithTag failed with 0x%x\n", status));
  8.1114 -    return FALSE;
  8.1115 -  }
  8.1116 -  NdisZeroMemory(xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount());
  8.1117 -
  8.1118 -  stack_new(&xi->rx_pb_stack, NET_RX_RING_SIZE * 4);
  8.1119 -
  8.1120 -  XenNet_BufferAlloc(xi);
  8.1121 -  
  8.1122 -  NdisAllocatePacketPool(&status, &xi->rx_packet_pool, NET_RX_RING_SIZE * 4,
  8.1123 -    PROTOCOL_RESERVED_SIZE_IN_PACKET);
  8.1124 -  if (status != NDIS_STATUS_SUCCESS)
  8.1125 -  {
  8.1126 -    KdPrint(("NdisAllocatePacketPool failed with 0x%x\n", status));
  8.1127 -    return FALSE;
  8.1128 -  }
  8.1129 -  stack_new(&xi->rx_packet_stack, NET_RX_RING_SIZE * 4);
  8.1130 -
  8.1131 -  NdisInitializeNPagedLookasideList(&xi->rx_lookaside_list, NULL, NULL, 0,
  8.1132 -    MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH + sizeof(shared_buffer_t), XENNET_POOL_TAG, 0);
  8.1133 -  
  8.1134 -  XenNet_FillRing(xi);
  8.1135 -
  8.1136 -  FUNCTION_EXIT();
  8.1137 -
  8.1138 -  return TRUE;
  8.1139 -}
  8.1140 -
  8.1141 -BOOLEAN
  8.1142 -XenNet_RxShutdown(xennet_info_t *xi)
  8.1143 -{
  8.1144 -  KIRQL old_irql;
  8.1145 -  PNDIS_PACKET packet;
  8.1146 -
  8.1147 -  FUNCTION_ENTER();
  8.1148 -
  8.1149 -  KeAcquireSpinLock(&xi->rx_lock, &old_irql);
  8.1150 -  xi->rx_shutting_down = TRUE;
  8.1151 -  KeReleaseSpinLock(&xi->rx_lock, old_irql);
  8.1152 -
  8.1153 -  if (xi->config_rx_interrupt_moderation)
  8.1154 -  {
  8.1155 -    KeCancelTimer(&xi->rx_timer);
  8.1156 -  }
  8.1157 -
  8.1158 -#if (NTDDI_VERSION >= NTDDI_WINXP)
  8.1159 -  KeFlushQueuedDpcs();
  8.1160 -#endif
  8.1161 -
  8.1162 -  while (xi->rx_outstanding)
  8.1163 -  {
  8.1164 -    KdPrint((__DRIVER_NAME "     Waiting for all packets to be returned\n"));
  8.1165 -    KeWaitForSingleObject(&xi->packet_returned_event, Executive, KernelMode, FALSE, NULL);
  8.1166 -  }
  8.1167 -
  8.1168 -  //KeAcquireSpinLock(&xi->rx_lock, &old_irql);
  8.1169 -
  8.1170 -  NdisFreeMemory(xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount(), 0);
  8.1171 -
  8.1172 -  XenNet_BufferFree(xi);
  8.1173 -
  8.1174 -  /* this works because get_packet_from_freelist won't allocate new packets when rx_shutting_down */
  8.1175 -  while ((packet = get_packet_from_freelist(xi)) != NULL)
  8.1176 -    NdisFreePacket(packet);
  8.1177 -  stack_delete(xi->rx_packet_stack, NULL, NULL);
  8.1178 -  NdisFreePacketPool(xi->rx_packet_pool);
  8.1179 -
  8.1180 -  NdisDeleteNPagedLookasideList(&xi->rx_lookaside_list);
  8.1181 -
  8.1182 -  stack_delete(xi->rx_pb_stack, NULL, NULL);
  8.1183 -  //KeReleaseSpinLock(&xi->rx_lock, old_irql);
  8.1184 -
  8.1185 -  FUNCTION_EXIT();
  8.1186 -
  8.1187 -  return TRUE;
  8.1188 -}
     9.1 --- a/xennet/xennet5_tx.c	Sun Feb 10 23:12:03 2013 +1100
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,715 +0,0 @@
     9.4 -/*
     9.5 -PV Net Driver for Windows Xen HVM Domains
     9.6 -Copyright (C) 2007 James Harper
     9.7 -Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
     9.8 -
     9.9 -This program is free software; you can redistribute it and/or
    9.10 -modify it under the terms of the GNU General Public License
    9.11 -as published by the Free Software Foundation; either version 2
    9.12 -of the License, or (at your option) any later version.
    9.13 -
    9.14 -This program is distributed in the hope that it will be useful,
    9.15 -but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.16 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    9.17 -GNU General Public License for more details.
    9.18 -
    9.19 -You should have received a copy of the GNU General Public License
    9.20 -along with this program; if not, write to the Free Software
    9.21 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    9.22 -*/
    9.23 -
    9.24 -#include "xennet5.h"
    9.25 -
    9.26 -static USHORT
    9.27 -get_id_from_freelist(struct xennet_info *xi)
    9.28 -{
    9.29 -  ASSERT(xi->tx_id_free);
    9.30 -  xi->tx_id_free--;
    9.31 -
    9.32 -  return xi->tx_id_list[xi->tx_id_free];
    9.33 -}
    9.34 -
    9.35 -static VOID
    9.36 -put_id_on_freelist(struct xennet_info *xi, USHORT id)
    9.37 -{
    9.38 -  xi->tx_id_list[xi->tx_id_free] = id;
    9.39 -  xi->tx_id_free++;
    9.40 -}
    9.41 -
    9.42 -#define SWAP_USHORT(x) (USHORT)((((x & 0xFF) << 8)|((x >> 8) & 0xFF)))
    9.43 -
    9.44 -static __forceinline struct netif_tx_request *
    9.45 -XenNet_PutCbOnRing(struct xennet_info *xi, PVOID coalesce_buf, ULONG length, grant_ref_t gref)
    9.46 -{
    9.47 -  struct netif_tx_request *tx;
    9.48 -  tx = RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
    9.49 -  xi->tx.req_prod_pvt++;
    9.50 -  xi->tx_ring_free--;
    9.51 -  tx->id = get_id_from_freelist(xi);
    9.52 -  ASSERT(xi->tx_shadows[tx->id].gref == INVALID_GRANT_REF);
    9.53 -  ASSERT(!xi->tx_shadows[tx->id].cb);
    9.54 -  xi->tx_shadows[tx->id].cb = coalesce_buf;
    9.55 -  tx->gref = xi->vectors.GntTbl_GrantAccess(xi->vectors.context, (ULONG)(MmGetPhysicalAddress(coalesce_buf).QuadPart >> PAGE_SHIFT), FALSE, gref, (ULONG)'XNTX');
    9.56 -  xi->tx_shadows[tx->id].gref = tx->gref;
    9.57 -  tx->offset = 0;
    9.58 -  tx->size = (USHORT)length;
    9.59 -  ASSERT(tx->offset + tx->size <= PAGE_SIZE);
    9.60 -  ASSERT(tx->size);
    9.61 -  return tx;
    9.62 -}
    9.63 -  
    9.64 -/* Called at DISPATCH_LEVEL with tx_lock held */
    9.65 -/*
    9.66 - * Send one NDIS_PACKET. This may involve multiple entries on TX ring.
    9.67 - */
    9.68 -static BOOLEAN
    9.69 -XenNet_HWSendPacket(struct xennet_info *xi, PNDIS_PACKET packet)
    9.70 -{
    9.71 -  struct netif_tx_request *tx0 = NULL;
    9.72 -  struct netif_tx_request *txN = NULL;
    9.73 -  struct netif_extra_info *ei = NULL;
    9.74 -  PNDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
    9.75 -  ULONG mss = 0;
    9.76 -  uint16_t flags = NETTXF_more_data;
    9.77 -  packet_info_t pi;
    9.78 -  BOOLEAN ndis_lso = FALSE;
    9.79 -  BOOLEAN xen_gso = FALSE;
    9.80 -  ULONG remaining;
    9.81 -  ULONG parse_result;
    9.82 -  ULONG frags = 0;
    9.83 -  BOOLEAN coalesce_required = FALSE;
    9.84 -  PVOID coalesce_buf;
    9.85 -  ULONG coalesce_remaining = 0;
    9.86 -  grant_ref_t gref;
    9.87 -  ULONG tx_length = 0;
    9.88 -  
    9.89 -  //FUNCTION_ENTER();
    9.90 -
    9.91 -  gref = xi->vectors.GntTbl_GetRef(xi->vectors.context, (ULONG)'XNTX');
    9.92 -  if (gref == INVALID_GRANT_REF)
    9.93 -  {
    9.94 -    KdPrint((__DRIVER_NAME "     out of grefs\n"));
    9.95 -    return FALSE;
    9.96 -  }
    9.97 -  coalesce_buf = NdisAllocateFromNPagedLookasideList(&xi->tx_lookaside_list);
    9.98 -  if (!coalesce_buf)
    9.99 -  {
   9.100 -    xi->vectors.GntTbl_PutRef(xi->vectors.context, gref, (ULONG)'XNTX');
   9.101 -    KdPrint((__DRIVER_NAME "     out of memory\n"));
   9.102 -    return FALSE;
   9.103 -  }
   9.104 -  XenNet_ClearPacketInfo(&pi);
   9.105 -  NdisQueryPacket(packet, NULL, (PUINT)&pi.mdl_count, &pi.first_buffer, (PUINT)&pi.total_length);
   9.106 -  
   9.107 -  pi.curr_mdl_offset = 0;
   9.108 -  pi.curr_buffer = pi.first_buffer;
   9.109 -  remaining = min(pi.total_length, PAGE_SIZE);
   9.110 -  while (remaining) /* this much gets put in the header */
   9.111 -  {
   9.112 -    ULONG length = XenNet_QueryData(&pi, remaining);
   9.113 -    remaining -= length;
   9.114 -    XenNet_EatData(&pi, length);
   9.115 -  }
   9.116 -  frags++;
   9.117 -  if (pi.total_length > PAGE_SIZE) /* these are the frags we care about */
   9.118 -  {
   9.119 -    remaining = pi.total_length - PAGE_SIZE;
   9.120 -    while (remaining)
   9.121 -    {
   9.122 -      ULONG length = XenNet_QueryData(&pi, PAGE_SIZE);
   9.123 -      if (length != 0)
   9.124 -      {
   9.125 -        frags++;
   9.126 -        if (frags > LINUX_MAX_SG_ELEMENTS)
   9.127 -          break; /* worst case there could be hundreds of fragments - leave the loop now */
   9.128 -      }
   9.129 -      remaining -= length;
   9.130 -      XenNet_EatData(&pi, length);
   9.131 -    }
   9.132 -  }
   9.133 -  if (frags > LINUX_MAX_SG_ELEMENTS)
   9.134 -  {
   9.135 -    frags = LINUX_MAX_SG_ELEMENTS;
   9.136 -    coalesce_required = TRUE;
   9.137 -  }
   9.138 -
   9.139 -  /* if we have enough space on the ring then we have enough id's so no need to check for that */
   9.140 -  if (xi->tx_ring_free < frags + 1)
   9.141 -  {
   9.142 -    xi->vectors.GntTbl_PutRef(xi->vectors.context, gref, (ULONG)'XNTX');
   9.143 -    NdisFreeToNPagedLookasideList(&xi->tx_lookaside_list, coalesce_buf);
   9.144 -    //KdPrint((__DRIVER_NAME "     Full on send - ring full\n"));
   9.145 -    return FALSE;
   9.146 -  }
   9.147 -  
   9.148 -  parse_result = XenNet_ParsePacketHeader(&pi, coalesce_buf, PAGE_SIZE);
   9.149 -  remaining = pi.total_length - pi.header_length;
   9.150 -
   9.151 -  if (NDIS_GET_PACKET_PROTOCOL_TYPE(packet) == NDIS_PROTOCOL_ID_TCP_IP)
   9.152 -  {
   9.153 -    csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
   9.154 -      packet, TcpIpChecksumPacketInfo);
   9.155 -    if (csum_info->Transmit.NdisPacketChecksumV4)
   9.156 -    {
   9.157 -      if (csum_info->Transmit.NdisPacketIpChecksum && !xi->setting_csum.V4Transmit.IpChecksum)
   9.158 -      {
   9.159 -        KdPrint((__DRIVER_NAME "     IpChecksum not enabled\n"));
   9.160 -        //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
   9.161 -        //return TRUE;
   9.162 -      }
   9.163 -      if (csum_info->Transmit.NdisPacketTcpChecksum)
   9.164 -      {
   9.165 -        if (xi->setting_csum.V4Transmit.TcpChecksum)
   9.166 -        {
   9.167 -          flags |= NETTXF_csum_blank | NETTXF_data_validated;
   9.168 -        }
   9.169 -        else
   9.170 -        {
   9.171 -          KdPrint((__DRIVER_NAME "     TcpChecksum not enabled\n"));
   9.172 -          //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
   9.173 -          //return TRUE;
   9.174 -        }
   9.175 -      }
   9.176 -      else if (csum_info->Transmit.NdisPacketUdpChecksum)
   9.177 -      {
   9.178 -        if (xi->setting_csum.V4Transmit.UdpChecksum)
   9.179 -        {
   9.180 -          flags |= NETTXF_csum_blank | NETTXF_data_validated;
   9.181 -        }
   9.182 -        else
   9.183 -        {
   9.184 -          KdPrint((__DRIVER_NAME "     UdpChecksum not enabled\n"));
   9.185 -          //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
   9.186 -          //return TRUE;
   9.187 -        }
   9.188 -      }
   9.189 -    }
   9.190 -    else if (csum_info->Transmit.NdisPacketChecksumV6)
   9.191 -    {
   9.192 -      KdPrint((__DRIVER_NAME "     NdisPacketChecksumV6 not supported\n"));
   9.193 -      //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
   9.194 -      //return TRUE;
   9.195 -    }
   9.196 -  }
   9.197 -  
   9.198 -  mss = PtrToUlong(NDIS_PER_PACKET_INFO_FROM_PACKET(packet, TcpLargeSendPacketInfo));
   9.199 -
   9.200 -  if (mss && parse_result == PARSE_OK)
   9.201 -  {
   9.202 -    if (NDIS_GET_PACKET_PROTOCOL_TYPE(packet) != NDIS_PROTOCOL_ID_TCP_IP)
   9.203 -    {
   9.204 -      KdPrint((__DRIVER_NAME "     mss specified when packet is not NDIS_PROTOCOL_ID_TCP_IP\n"));
   9.205 -    }
   9.206 -    ndis_lso = TRUE;
   9.207 -    if (mss > xi->setting_max_offload)
   9.208 -    {
   9.209 -      KdPrint((__DRIVER_NAME "     Requested MSS (%d) larger than allowed MSS (%d)\n", mss, xi->setting_max_offload));
   9.210 -      //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
   9.211 -      //FUNCTION_EXIT();
   9.212 -      return TRUE;
   9.213 -    }
   9.214 -  }
   9.215 -
   9.216 -  if (ndis_lso)
   9.217 -  {    
   9.218 -    flags |= NETTXF_csum_blank | NETTXF_data_validated; /* these may be implied but not specified when lso is used*/
   9.219 -    if (pi.tcp_length >= mss)
   9.220 -    {
   9.221 -      flags |= NETTXF_extra_info;
   9.222 -      xen_gso = TRUE;
   9.223 -    }
   9.224 -    else
   9.225 -    {
   9.226 -      KdPrint((__DRIVER_NAME "     large send specified when tcp_length < mss\n"));
   9.227 -    }
   9.228 -  }
   9.229 -
   9.230 -/*
   9.231 -* See io/netif.h. Must put (A) 1st request, then (B) optional extra_info, then
   9.232 -* (C) rest of requests on the ring. Only (A) has csum flags.
   9.233 -*/
   9.234 -
   9.235 -  /* (A) */
   9.236 -  tx0 = XenNet_PutCbOnRing(xi, coalesce_buf, pi.header_length, gref);
   9.237 -  ASSERT(tx0); /* this will never happen */
   9.238 -  tx0->flags = flags;
   9.239 -  tx_length += pi.header_length;
   9.240 -
   9.241 -  /* even though we haven't reported that we are capable of it, LSO demands that we calculate the IP Header checksum */
   9.242 -  if (ndis_lso)
   9.243 -  {
   9.244 -    XenNet_SumIpHeader(coalesce_buf, pi.ip4_header_length);
   9.245 -  }
   9.246 -  txN = tx0;
   9.247 -
   9.248 -  /* (B) */
   9.249 -  if (xen_gso)
   9.250 -  {
   9.251 -    ASSERT(flags & NETTXF_extra_info);
   9.252 -    ei = (struct netif_extra_info *)RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
   9.253 -    //KdPrint((__DRIVER_NAME "     pos = %d\n", xi->tx.req_prod_pvt));
   9.254 -    xi->tx.req_prod_pvt++;
   9.255 -    xi->tx_ring_free--;
   9.256 -    ei->type = XEN_NETIF_EXTRA_TYPE_GSO;
   9.257 -    ei->flags = 0;
   9.258 -    ei->u.gso.size = (USHORT)mss;
   9.259 -    ei->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4;
   9.260 -    ei->u.gso.pad = 0;
   9.261 -    ei->u.gso.features = 0;
   9.262 -  }
   9.263 -
   9.264 -  ASSERT(xi->config_sg || !remaining);
   9.265 -  
   9.266 -  /* (C) - only if data is remaining */
   9.267 -  coalesce_buf = NULL;
   9.268 -  while (remaining > 0)
   9.269 -  {
   9.270 -    ULONG length;
   9.271 -    PFN_NUMBER pfn;
   9.272 -    
   9.273 -    ASSERT(pi.curr_buffer);
   9.274 -    if (coalesce_required)
   9.275 -    {
   9.276 -      PVOID va;
   9.277 -      if (!coalesce_buf)
   9.278 -      {
   9.279 -        gref = xi->vectors.GntTbl_GetRef(xi->vectors.context, (ULONG)'XNTX');
   9.280 -        if (gref == INVALID_GRANT_REF)
   9.281 -        {
   9.282 -          KdPrint((__DRIVER_NAME "     out of grefs - partial send\n"));
   9.283 -          break;
   9.284 -        }
   9.285 -        coalesce_buf = NdisAllocateFromNPagedLookasideList(&xi->tx_lookaside_list);
   9.286 -        if (!coalesce_buf)
   9.287 -        {
   9.288 -          xi->vectors.GntTbl_PutRef(xi->vectors.context, gref, (ULONG)'XNTX');
   9.289 -          KdPrint((__DRIVER_NAME "     out of memory - partial send\n"));
   9.290 -          break;
   9.291 -        }
   9.292 -        coalesce_remaining = min(PAGE_SIZE, remaining);
   9.293 -      }
   9.294 -      length = XenNet_QueryData(&pi, coalesce_remaining);
   9.295 -      va = NdisBufferVirtualAddressSafe(pi.curr_buffer, LowPagePriority);
   9.296 -      if (!va)
   9.297 -      {
   9.298 -        KdPrint((__DRIVER_NAME "     failed to map buffer va - partial send\n"));
   9.299 -        coalesce_remaining = 0;
   9.300 -        remaining -= min(PAGE_SIZE, remaining);
   9.301 -        NdisFreeToNPagedLookasideList(&xi->tx_lookaside_list, coalesce_buf);
   9.302 -      }
   9.303 -      else
   9.304 -      {
   9.305 -        memcpy((PUCHAR)coalesce_buf + min(PAGE_SIZE, remaining) - coalesce_remaining, (PUCHAR)va + pi.curr_mdl_offset, length);
   9.306 -        coalesce_remaining -= length;
   9.307 -      }
   9.308 -    }
   9.309 -    else
   9.310 -    {
   9.311 -      length = XenNet_QueryData(&pi, PAGE_SIZE);
   9.312 -    }
   9.313 -    if (!length || coalesce_remaining) /* sometimes there are zero length buffers... */
   9.314 -    {
   9.315 -      XenNet_EatData(&pi, length); /* do this so we actually move to the next buffer */
   9.316 -      continue;
   9.317 -    }
   9.318 -
   9.319 -    if (coalesce_buf)
   9.320 -    {
   9.321 -      if (remaining)
   9.322 -      {
   9.323 -        txN = XenNet_PutCbOnRing(xi, coalesce_buf, min(PAGE_SIZE, remaining), gref);
   9.324 -        ASSERT(txN);
   9.325 -        coalesce_buf = NULL;
   9.326 -        remaining -= min(PAGE_SIZE, remaining);
   9.327 -        tx_length += min(PAGE_SIZE, remaining);
   9.328 -      }
   9.329 -    }
   9.330 -    else
   9.331 -    {
   9.332 -      ULONG offset;
   9.333 -      
   9.334 -      gref = xi->vectors.GntTbl_GetRef(xi->vectors.context, (ULONG)'XNTX');
   9.335 -      if (gref == INVALID_GRANT_REF)
   9.336 -      {
   9.337 -        KdPrint((__DRIVER_NAME "     out of grefs - partial send\n"));
   9.338 -        break;
   9.339 -      }
   9.340 -      txN = RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
   9.341 -      xi->tx.req_prod_pvt++;
   9.342 -      xi->tx_ring_free--;
   9.343 -      txN->id = get_id_from_freelist(xi);
   9.344 -      ASSERT(!xi->tx_shadows[txN->id].cb);
   9.345 -      offset = MmGetMdlByteOffset(pi.curr_buffer) + pi.curr_mdl_offset;
   9.346 -      pfn = MmGetMdlPfnArray(pi.curr_buffer)[offset >> PAGE_SHIFT];
   9.347 -      txN->offset = (USHORT)offset & (PAGE_SIZE - 1);
   9.348 -      txN->gref = xi->vectors.GntTbl_GrantAccess(xi->vectors.context, (ULONG)pfn, FALSE, gref, (ULONG)'XNTX');
   9.349 -      ASSERT(xi->tx_shadows[txN->id].gref == INVALID_GRANT_REF);
   9.350 -      xi->tx_shadows[txN->id].gref = txN->gref;
   9.351 -      //ASSERT(sg->Elements[sg_element].Length > sg_offset);
   9.352 -      txN->size = (USHORT)length;
   9.353 -      ASSERT(txN->offset + txN->size <= PAGE_SIZE);
   9.354 -      ASSERT(txN->size);
   9.355 -      ASSERT(txN->gref != INVALID_GRANT_REF);
   9.356 -      remaining -= length;
   9.357 -      tx_length += length;
   9.358 -    }
   9.359 -    tx0->size = tx0->size + txN->size;
   9.360 -    txN->flags = NETTXF_more_data;
   9.361 -    XenNet_EatData(&pi, length);
   9.362 -  }
   9.363 -  txN->flags &= ~NETTXF_more_data;
   9.364 -  ASSERT(tx0->size == pi.total_length);
   9.365 -  ASSERT(!xi->tx_shadows[txN->id].packet);
   9.366 -  xi->tx_shadows[txN->id].packet = packet;
   9.367 -
   9.368 -  if (ndis_lso)
   9.369 -  {
   9.370 -    //KdPrint((__DRIVER_NAME "     TcpLargeSendPacketInfo = %d\n", pi.tcp_length));
   9.371 -    NDIS_PER_PACKET_INFO_FROM_PACKET(packet, TcpLargeSendPacketInfo) = UlongToPtr(tx_length - MAX_ETH_HEADER_LENGTH - pi.ip4_header_length - pi.tcp_header_length);
   9.372 -  }
   9.373 -
   9.374 -  xi->stat_tx_ok++;
   9.375 -
   9.376 -  //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
   9.377 -  //FUNCTION_EXIT();
   9.378 -  xi->tx_outstanding++;
   9.379 -  return TRUE;
   9.380 -}
   9.381 -
   9.382 -/* Called at DISPATCH_LEVEL with tx_lock held */
   9.383 -
   9.384 -static VOID
   9.385 -XenNet_SendQueuedPackets(struct xennet_info *xi)
   9.386 -{
   9.387 -  PLIST_ENTRY entry;
   9.388 -  PNDIS_PACKET packet;
   9.389 -  int notify;
   9.390 -
   9.391 -  //FUNCTION_ENTER();
   9.392 -
   9.393 -  if (xi->device_state->suspend_resume_state_pdo != SR_STATE_RUNNING)
   9.394 -    return;
   9.395 -
   9.396 -  entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
   9.397 -  /* if empty, the above returns head*, not NULL */
   9.398 -  while (entry != &xi->tx_waiting_pkt_list)
   9.399 -  {
   9.400 -    packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
   9.401 -    if (!XenNet_HWSendPacket(xi, packet))
   9.402 -    {
   9.403 -      //KdPrint((__DRIVER_NAME "     No room for packet\n"));
   9.404 -      InsertHeadList(&xi->tx_waiting_pkt_list, entry);
   9.405 -      break;
   9.406 -    }
   9.407 -    entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
   9.408 -  }
   9.409 -
   9.410 -  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xi->tx, notify);
   9.411 -  if (notify)
   9.412 -  {
   9.413 -    xi->vectors.EvtChn_Notify(xi->vectors.context, xi->event_channel);
   9.414 -  }
   9.415 -  //FUNCTION_EXIT();
   9.416 -}
   9.417 -
   9.418 -//ULONG packets_outstanding = 0;
   9.419 -// Called at DISPATCH_LEVEL
   9.420 -VOID
   9.421 -XenNet_TxBufferGC(struct xennet_info *xi, BOOLEAN dont_set_event)
   9.422 -{
   9.423 -  RING_IDX cons, prod;
   9.424 -  PNDIS_PACKET head = NULL, tail = NULL;
   9.425 -  PNDIS_PACKET packet;
   9.426 -  ULONG tx_packets = 0;
   9.427 -
   9.428 -  //FUNCTION_ENTER();
   9.429 -
   9.430 -  if (!xi->connected)
   9.431 -    return; /* a delayed DPC could let this come through... just do nothing */
   9.432 -  ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
   9.433 -
   9.434 -  KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
   9.435 -
   9.436 -  if (xi->tx_shutting_down && !xi->tx_outstanding)
   9.437 -  {
   9.438 -    /* there is a chance that our Dpc had been queued just before the shutdown... */
   9.439 -    KeSetEvent(&xi->tx_idle_event, IO_NO_INCREMENT, FALSE);
   9.440 -    KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
   9.441 -    return;
   9.442 -  }
   9.443 -
   9.444 -  do {
   9.445 -    prod = xi->tx.sring->rsp_prod;
   9.446 -    KeMemoryBarrier(); /* Ensure we see responses up to 'rsp_prod'. */
   9.447 -
   9.448 -    for (cons = xi->tx.rsp_cons; cons != prod; cons++)
   9.449 -    {
   9.450 -      struct netif_tx_response *txrsp;
   9.451 -      tx_shadow_t *shadow;
   9.452 -      
   9.453 -      txrsp = RING_GET_RESPONSE(&xi->tx, cons);
   9.454 -      
   9.455 -      xi->tx_ring_free++;
   9.456 -      
   9.457 -      if (txrsp->status == NETIF_RSP_NULL)
   9.458 -      {
   9.459 -        continue;
   9.460 -      }
   9.461 -
   9.462 -      shadow = &xi->tx_shadows[txrsp->id];
   9.463 -      if (shadow->cb)
   9.464 -      {
   9.465 -        NdisFreeToNPagedLookasideList(&xi->tx_lookaside_list, shadow->cb);
   9.466 -        shadow->cb = NULL;
   9.467 -      }
   9.468 -      
   9.469 -      if (shadow->gref != INVALID_GRANT_REF)
   9.470 -      {
   9.471 -        xi->vectors.GntTbl_EndAccess(xi->vectors.context,
   9.472 -          shadow->gref, FALSE, (ULONG)'XNTX');
   9.473 -        shadow->gref = INVALID_GRANT_REF;
   9.474 -      }
   9.475 -      
   9.476 -      if (shadow->packet)
   9.477 -      {
   9.478 -        packet = shadow->packet;
   9.479 -        *(PNDIS_PACKET *)&packet->MiniportReservedEx[0] = NULL;
   9.480 -        if (head)
   9.481 -          *(PNDIS_PACKET *)&tail->MiniportReservedEx[0] = packet;
   9.482 -        else
   9.483 -          head = packet;
   9.484 -        tail = packet;
   9.485 -        shadow->packet = NULL;
   9.486 -      }
   9.487 -      put_id_on_freelist(xi, txrsp->id);
   9.488 -    }
   9.489 -
   9.490 -    xi->tx.rsp_cons = prod;
   9.491 -    /* resist the temptation to set the event more than +1... it breaks things */
   9.492 -    if (!dont_set_event)
   9.493 -      xi->tx.sring->rsp_event = prod + 1;
   9.494 -    KeMemoryBarrier();
   9.495 -  } while (prod != xi->tx.sring->rsp_prod);
   9.496 -
   9.497 -  /* if queued packets, send them now */
   9.498 -  if (!xi->tx_shutting_down)
   9.499 -    XenNet_SendQueuedPackets(xi);
   9.500 -
   9.501 -  KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
   9.502 -
   9.503 -  /* must be done without holding any locks */
   9.504 -  while (head)
   9.505 -  {
   9.506 -    packet = (PNDIS_PACKET)head;
   9.507 -    head = *(PNDIS_PACKET *)&packet->MiniportReservedEx[0];
   9.508 -    NdisMSendComplete(xi->adapter_handle, packet, NDIS_STATUS_SUCCESS);
   9.509 -    tx_packets++;
   9.510 -  }
   9.511 -
   9.512 -  /* must be done after we have truly given back all packets */
   9.513 -  KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
   9.514 -  xi->tx_outstanding -= tx_packets;
   9.515 -  if (!xi->tx_outstanding && xi->tx_shutting_down)
   9.516 -    KeSetEvent(&xi->tx_idle_event, IO_NO_INCREMENT, FALSE);
   9.517 -  KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
   9.518 -
   9.519 -  if (xi->device_state->suspend_resume_state_pdo == SR_STATE_SUSPENDING
   9.520 -    && xi->device_state->suspend_resume_state_fdo != SR_STATE_SUSPENDING
   9.521 -    && xi->tx_id_free == NET_TX_RING_SIZE)
   9.522 -  {
   9.523 -    KdPrint((__DRIVER_NAME "     Setting SR_STATE_SUSPENDING\n"));
   9.524 -    xi->device_state->suspend_resume_state_fdo = SR_STATE_SUSPENDING;
   9.525 -    KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xi->device_state->pdo_event_channel));
   9.526 -    xi->vectors.EvtChn_Notify(xi->vectors.context, xi->device_state->pdo_event_channel);
   9.527 -  }
   9.528 -
   9.529 -  //FUNCTION_EXIT();
   9.530 -}
   9.531 -
   9.532 -// called at <= DISPATCH_LEVEL
   9.533 -VOID
   9.534 -XenNet_SendPackets(
   9.535 -  IN NDIS_HANDLE MiniportAdapterContext,
   9.536 -  IN PPNDIS_PACKET PacketArray,
   9.537 -  IN UINT NumberOfPackets
   9.538 -  )
   9.539 -{
   9.540 -  struct xennet_info *xi = MiniportAdapterContext;
   9.541 -  PNDIS_PACKET packet;
   9.542 -  UINT i;
   9.543 -  PLIST_ENTRY entry;
   9.544 -  KIRQL OldIrql;
   9.545 -
   9.546 -  //FUNCTION_ENTER();
   9.547 -
   9.548 -  if (xi->inactive)
   9.549 -  {
   9.550 -    for (i = 0; i < NumberOfPackets; i++)
   9.551 -    {
   9.552 -      NdisMSendComplete(xi->adapter_handle, PacketArray[i], NDIS_STATUS_FAILURE);
   9.553 -    }
   9.554 -    return;
   9.555 -  }
   9.556 -    
   9.557 -  KeAcquireSpinLock(&xi->tx_lock, &OldIrql);
   9.558 -
   9.559 -  for (i = 0; i < NumberOfPackets; i++)
   9.560 -  {
   9.561 -    packet = PacketArray[i];
   9.562 -    ASSERT(packet);
   9.563 -    *(ULONG *)&packet->MiniportReservedEx = 0;
   9.564 -    entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
   9.565 -    InsertTailList(&xi->tx_waiting_pkt_list, entry);
   9.566 -  }
   9.567 -
   9.568 -  XenNet_SendQueuedPackets(xi);
   9.569 -
   9.570 -  KeReleaseSpinLock(&xi->tx_lock, OldIrql);
   9.571 -  
   9.572 -  //FUNCTION_EXIT();
   9.573 -}
   9.574 -
   9.575 -VOID
   9.576 -XenNet_CancelSendPackets(
   9.577 -  NDIS_HANDLE MiniportAdapterContext,
   9.578 -  PVOID CancelId)
   9.579 -{
   9.580 -  struct xennet_info *xi = MiniportAdapterContext;
   9.581 -  KIRQL old_irql;
   9.582 -  PLIST_ENTRY entry;
   9.583 -  PNDIS_PACKET packet;
   9.584 -  PNDIS_PACKET head = NULL, tail = NULL;
   9.585 -  BOOLEAN result;
   9.586 -
   9.587 -  FUNCTION_ENTER();
   9.588 -
   9.589 -  KeAcquireSpinLock(&xi->tx_lock, &old_irql);
   9.590 -
   9.591 -  entry = xi->tx_waiting_pkt_list.Flink;
   9.592 -  while (entry != &xi->tx_waiting_pkt_list)
   9.593 -  {
   9.594 -    packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
   9.595 -    entry = entry->Flink;
   9.596 -    if (NDIS_GET_PACKET_CANCEL_ID(packet) == CancelId)
   9.597 -    {
   9.598 -      KdPrint((__DRIVER_NAME "     Found packet to cancel %p\n", packet));
   9.599 -      result = RemoveEntryList((PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)]);
   9.600 -      ASSERT(result);
   9.601 -      *(PNDIS_PACKET *)&packet->MiniportReservedEx[0] = NULL;
   9.602 -      if (head)
   9.603 -        *(PNDIS_PACKET *)&tail->MiniportReservedEx[0] = packet;
   9.604 -      else
   9.605 -        head = packet;
   9.606 -      tail = packet;
   9.607 -    }
   9.608 -  }
   9.609 -
   9.610 -  KeReleaseSpinLock(&xi->tx_lock, old_irql);
   9.611 -
   9.612 -  while (head)
   9.613 -  {
   9.614 -    packet = (PNDIS_PACKET)head;
   9.615 -    head = *(PNDIS_PACKET *)&packet->MiniportReservedEx[0];
   9.616 -    KdPrint((__DRIVER_NAME "     NdisMSendComplete(%p)\n", packet));
   9.617 -    NdisMSendComplete(xi->adapter_handle, packet, NDIS_STATUS_REQUEST_ABORTED);
   9.618 -  }
   9.619 -  
   9.620 -  FUNCTION_EXIT();
   9.621 -}
   9.622 -
   9.623 -VOID
   9.624 -XenNet_TxResumeStart(xennet_info_t *xi)
   9.625 -{
   9.626 -  UNREFERENCED_PARAMETER(xi);
   9.627 -
   9.628 -  FUNCTION_ENTER();
   9.629 -    /* nothing to do here - all packets were already sent */
   9.630 -  FUNCTION_EXIT();
   9.631 -}
   9.632 -
   9.633 -VOID
   9.634 -XenNet_TxResumeEnd(xennet_info_t *xi)
   9.635 -{
   9.636 -  KIRQL old_irql;
   9.637 -
   9.638 -  FUNCTION_ENTER();
   9.639 -
   9.640 -  KeAcquireSpinLock(&xi->tx_lock, &old_irql);
   9.641 -  XenNet_SendQueuedPackets(xi);
   9.642 -  KeReleaseSpinLock(&xi->tx_lock, old_irql);
   9.643 -
   9.644 -  FUNCTION_EXIT();
   9.645 -}
   9.646 -
   9.647 -BOOLEAN
   9.648 -XenNet_TxInit(xennet_info_t *xi)
   9.649 -{
   9.650 -  USHORT i;
   9.651 -
   9.652 -  KeInitializeSpinLock(&xi->tx_lock);
   9.653 -  InitializeListHead(&xi->tx_waiting_pkt_list);
   9.654 -
   9.655 -  KeInitializeEvent(&xi->tx_idle_event, SynchronizationEvent, FALSE);
   9.656 -  xi->tx_shutting_down = FALSE;
   9.657 -  xi->tx_outstanding = 0;
   9.658 -  xi->tx_ring_free = NET_TX_RING_SIZE;
   9.659 -  
   9.660 -  NdisInitializeNPagedLookasideList(&xi->tx_lookaside_list, NULL, NULL, 0,
   9.661 -    PAGE_SIZE, XENNET_POOL_TAG, 0);
   9.662 -
   9.663 -  xi->tx_id_free = 0;
   9.664 -  for (i = 0; i < NET_TX_RING_SIZE; i++)
   9.665 -  {
   9.666 -    xi->tx_shadows[i].gref = INVALID_GRANT_REF;
   9.667 -    xi->tx_shadows[i].cb = NULL;
   9.668 -    put_id_on_freelist(xi, i);
   9.669 -  }
   9.670 -
   9.671 -  return TRUE;
   9.672 -}
   9.673 -
   9.674 -/*
   9.675 -The ring is completely closed down now. We just need to empty anything left
   9.676 -on our freelists and harvest anything left on the rings.
   9.677 -*/
   9.678 -
   9.679 -BOOLEAN
   9.680 -XenNet_TxShutdown(xennet_info_t *xi)
   9.681 -{
   9.682 -  PLIST_ENTRY entry;
   9.683 -  PNDIS_PACKET packet;
   9.684 -  //PMDL mdl;
   9.685 -  //ULONG i;
   9.686 -  KIRQL OldIrql;
   9.687 -
   9.688 -  FUNCTION_ENTER();
   9.689 -
   9.690 -  KeAcquireSpinLock(&xi->tx_lock, &OldIrql);
   9.691 -  xi->tx_shutting_down = TRUE;
   9.692 -  KeReleaseSpinLock(&xi->tx_lock, OldIrql);
   9.693 -
   9.694 -  while (xi->tx_outstanding)
   9.695 -  {
   9.696 -    KdPrint((__DRIVER_NAME "     Waiting for %d remaining packets to be sent\n", xi->tx_outstanding));
   9.697 -    KeWaitForSingleObject(&xi->tx_idle_event, Executive, KernelMode, FALSE, NULL);
   9.698 -  }
   9.699 -
   9.700 -#if (NTDDI_VERSION >= NTDDI_WINXP)
   9.701 -  KeFlushQueuedDpcs();
   9.702 -#endif
   9.703 -
   9.704 -  /* Free packets in tx queue */
   9.705 -  entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
   9.706 -  while (entry != &xi->tx_waiting_pkt_list)
   9.707 -  {
   9.708 -    packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
   9.709 -    NdisMSendComplete(xi->adapter_handle, packet, NDIS_STATUS_FAILURE);
   9.710 -    entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
   9.711 -  }
   9.712 -
   9.713 -  NdisDeleteNPagedLookasideList(&xi->tx_lookaside_list);
   9.714 -
   9.715 -  FUNCTION_EXIT();
   9.716 -
   9.717 -  return TRUE;
   9.718 -}
    10.1 --- a/xennet/xennet6.c	Sun Feb 10 23:12:03 2013 +1100
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,887 +0,0 @@
    10.4 -/*
    10.5 -PV Net Driver for Windows Xen HVM Domains
    10.6 -Copyright (C) 2007 James Harper
    10.7 -Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
    10.8 -
    10.9 -This program is free software; you can redistribute it and/or
   10.10 -modify it under the terms of the GNU General Public License
   10.11 -as published by the Free Software Foundation; either version 2
   10.12 -of the License, or (at your option) any later version.
   10.13 -
   10.14 -This program is distributed in the hope that it will be useful,
   10.15 -but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.16 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   10.17 -GNU General Public License for more details.
   10.18 -
   10.19 -You should have received a copy of the GNU General Public License
   10.20 -along with this program; if not, write to the Free Software
   10.21 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   10.22 -*/
   10.23 -
   10.24 -#include <stdlib.h>
   10.25 -#include <io/xenbus.h>
   10.26 -#include "xennet6.h"
   10.27 -
   10.28 -/* Not really necessary but keeps PREfast happy */
   10.29 -DRIVER_INITIALIZE DriverEntry;
   10.30 -static IO_WORKITEM_ROUTINE XenNet_ResumeWorkItem;
   10.31 -#if (VER_PRODUCTBUILD >= 7600)
   10.32 -//static KDEFERRED_ROUTINE XenNet_SuspendResume;
   10.33 -static KDEFERRED_ROUTINE XenNet_RxTxDpc;
   10.34 -#endif
   10.35 -static VOID XenNet_DeviceCallback(PVOID context, ULONG callback_type, PVOID value);
   10.36 -
   10.37 -#pragma NDIS_INIT_FUNCTION(DriverEntry)
   10.38 -
   10.39 -NDIS_HANDLE driver_handle = NULL;
   10.40 -
   10.41 -USHORT ndis_os_major_version = 0;
   10.42 -USHORT ndis_os_minor_version = 0;
   10.43 -
   10.44 -static VOID
   10.45 -XenNet_RxTxDpc(PKDPC dpc, PVOID context, PVOID arg1, PVOID arg2)
   10.46 -{
   10.47 -  struct xennet_info *xi = context;
   10.48 -  BOOLEAN dont_set_event;
   10.49 -
   10.50 -  UNREFERENCED_PARAMETER(dpc);
   10.51 -  UNREFERENCED_PARAMETER(arg1);
   10.52 -  UNREFERENCED_PARAMETER(arg2);
   10.53 -
   10.54 -  //FUNCTION_ENTER();
   10.55 -  /* 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 */
   10.56 -  dont_set_event = XenNet_RxBufferCheck(xi);
   10.57 -  XenNet_TxBufferGC(xi, dont_set_event);
   10.58 -  //FUNCTION_EXIT();
   10.59 -} 
   10.60 -
   10.61 -static BOOLEAN
   10.62 -XenNet_HandleEvent_DIRQL(PVOID context)
   10.63 -{
   10.64 -  struct xennet_info *xi = context;
   10.65 -  //ULONG suspend_resume_state_pdo;
   10.66 -  
   10.67 -  //FUNCTION_ENTER();
   10.68 -  if (xi->device_state == DEVICE_STATE_ACTIVE || xi->device_state == DEVICE_STATE_DISCONNECTING) {
   10.69 -    KeInsertQueueDpc(&xi->rxtx_dpc, NULL, NULL);
   10.70 -  }
   10.71 -  //FUNCTION_EXIT();
   10.72 -  return TRUE;
   10.73 -}
   10.74 -
   10.75 -static NTSTATUS
   10.76 -XenNet_Connect(PVOID context, BOOLEAN suspend) {
   10.77 -  NTSTATUS status;
   10.78 -  struct xennet_info *xi = context;
   10.79 -  PFN_NUMBER pfn;
   10.80 -  ULONG qemu_hide_filter;
   10.81 -  ULONG qemu_hide_flags_value;
   10.82 -  int i;
   10.83 -  ULONG state;
   10.84 -  ULONG octet;
   10.85 -  PCHAR tmp_string;
   10.86 -  ULONG tmp_ulong;
   10.87 -
   10.88 -  if (!suspend) {
   10.89 -    xi->handle = XnOpenDevice(xi->pdo, XenNet_DeviceCallback, xi);
   10.90 -  }
   10.91 -  if (!xi->handle) {
   10.92 -    FUNCTION_MSG("Cannot open Xen device\n");
   10.93 -    return STATUS_UNSUCCESSFUL;
   10.94 -  }
   10.95 -  XnGetValue(xi->handle, XN_VALUE_TYPE_QEMU_HIDE_FLAGS, &qemu_hide_flags_value);
   10.96 -  XnGetValue(xi->handle, XN_VALUE_TYPE_QEMU_FILTER, &qemu_hide_filter);
   10.97 -  if (!(qemu_hide_flags_value & QEMU_UNPLUG_ALL_NICS) || qemu_hide_filter) {
   10.98 -    FUNCTION_MSG("inactive\n");
   10.99 -    xi->device_state = DEVICE_STATE_INACTIVE;
  10.100 -    XnCloseDevice(xi->handle);
  10.101 -    return STATUS_SUCCESS;
  10.102 -  }
  10.103 -
  10.104 -  for (i = 0; i <= 5 && xi->backend_state != XenbusStateInitialising && xi->backend_state != XenbusStateInitWait && xi->backend_state != XenbusStateInitialised; i++) {
  10.105 -    FUNCTION_MSG("Waiting for XenbusStateInitXxx\n");
  10.106 -    KeWaitForSingleObject(&xi->backend_event, Executive, KernelMode, FALSE, NULL);
  10.107 -  }
  10.108 -  if (xi->backend_state != XenbusStateInitialising && xi->backend_state != XenbusStateInitWait && xi->backend_state != XenbusStateInitialised) {
  10.109 -    FUNCTION_MSG("Backend state timeout\n");
  10.110 -    return STATUS_UNSUCCESSFUL;
  10.111 -  }
  10.112 -  if (!NT_SUCCESS(status = XnBindEvent(xi->handle, &xi->event_channel, XenNet_HandleEvent_DIRQL, xi))) {
  10.113 -    FUNCTION_MSG("Cannot allocate event channel\n");
  10.114 -    return STATUS_UNSUCCESSFUL;
  10.115 -  }
  10.116 -  FUNCTION_MSG("event_channel = %d\n", xi->event_channel);
  10.117 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "event-channel", xi->event_channel);
  10.118 -  xi->tx_sring = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENNET_POOL_TAG);
  10.119 -  if (!xi->tx_sring) {
  10.120 -    FUNCTION_MSG("Cannot allocate tx_sring\n");
  10.121 -    return STATUS_UNSUCCESSFUL;
  10.122 -  }
  10.123 -  SHARED_RING_INIT(xi->tx_sring);
  10.124 -  FRONT_RING_INIT(&xi->tx_ring, xi->tx_sring, PAGE_SIZE);
  10.125 -  pfn = MmGetPhysicalAddress(xi->tx_sring).QuadPart >> PAGE_SHIFT;
  10.126 -  FUNCTION_MSG("tx sring pfn = %d\n", (ULONG)pfn);
  10.127 -  xi->tx_sring_gref = XnGrantAccess(xi->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, XENNET_POOL_TAG);
  10.128 -  FUNCTION_MSG("tx sring_gref = %d\n", xi->tx_sring_gref);
  10.129 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "tx-ring-ref", xi->tx_sring_gref);  
  10.130 -  xi->rx_sring = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENNET_POOL_TAG);
  10.131 -  if (!xi->rx_sring) {
  10.132 -    FUNCTION_MSG("Cannot allocate rx_sring\n");
  10.133 -    return STATUS_UNSUCCESSFUL;
  10.134 -  }
  10.135 -  SHARED_RING_INIT(xi->rx_sring);
  10.136 -  FRONT_RING_INIT(&xi->rx_ring, xi->rx_sring, PAGE_SIZE);
  10.137 -  pfn = MmGetPhysicalAddress(xi->rx_sring).QuadPart >> PAGE_SHIFT;
  10.138 -  FUNCTION_MSG("rx sring pfn = %d\n", (ULONG)pfn);
  10.139 -  xi->rx_sring_gref = XnGrantAccess(xi->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, XENNET_POOL_TAG);
  10.140 -  FUNCTION_MSG("rx sring_gref = %d\n", xi->rx_sring_gref);
  10.141 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "rx-ring-ref", xi->rx_sring_gref);  
  10.142 -
  10.143 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "request-rx-copy", 1);
  10.144 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "request-rx-notify", 1);
  10.145 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-no-csum-offload", !xi->frontend_csum_supported);
  10.146 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-sg", (int)xi->frontend_sg_supported);
  10.147 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-gso-tcpv4", !!xi->frontend_gso_value);
  10.148 -
  10.149 -  status = XnReadInt32(xi->handle, XN_BASE_BACKEND, "feature-sg", &tmp_ulong);
  10.150 -  if (tmp_ulong) {
  10.151 -    xi->backend_sg_supported = TRUE;
  10.152 -  }
  10.153 -  status = XnReadInt32(xi->handle, XN_BASE_BACKEND, "feature-gso-tcpv4", &tmp_ulong);
  10.154 -  if (tmp_ulong) {
  10.155 -    xi->backend_gso_value = xi->frontend_gso_value;
  10.156 -  }
  10.157 -
  10.158 -  status = XnReadString(xi->handle, XN_BASE_BACKEND, "mac", &tmp_string);
  10.159 -  state = 0;
  10.160 -  octet = 0;
  10.161 -  for (i = 0; state != 3 && i < strlen(tmp_string); i++) {
  10.162 -    if (octet == 6) {
  10.163 -      state = 3;
  10.164 -      break;
  10.165 -    }
  10.166 -    switch(state) {
  10.167 -    case 0:
  10.168 -    case 1:
  10.169 -      if (tmp_string[i] >= '0' && tmp_string[i] <= '9') {
  10.170 -        xi->perm_mac_addr[octet] |= (tmp_string[i] - '0') << ((1 - state) * 4);
  10.171 -        state++;
  10.172 -      } else if (tmp_string[i] >= 'A' && tmp_string[i] <= 'F') {
  10.173 -        xi->perm_mac_addr[octet] |= (tmp_string[i] - 'A' + 10) << ((1 - state) * 4);
  10.174 -        state++;
  10.175 -      } else if (tmp_string[i] >= 'a' && tmp_string[i] <= 'f') {
  10.176 -        xi->perm_mac_addr[octet] |= (tmp_string[i] - 'a' + 10) << ((1 - state) * 4);
  10.177 -        state++;
  10.178 -      } else {
  10.179 -        state = 3;
  10.180 -      }
  10.181 -      break;
  10.182 -    case 2:
  10.183 -      if (tmp_string[i] == ':') {
  10.184 -        octet++;
  10.185 -        state = 0;
  10.186 -      } else {
  10.187 -        state = 3;
  10.188 -      }
  10.189 -      break;
  10.190 -    }
  10.191 -  }
  10.192 -  if (octet != 5 || state != 2) {
  10.193 -    FUNCTION_MSG("Failed to parse backend MAC address %s\n", tmp_string);
  10.194 -    XnFreeMem(xi->handle, tmp_string);
  10.195 -    return STATUS_UNSUCCESSFUL;
  10.196 -  } else if ((xi->curr_mac_addr[0] & 0x03) != 0x02) {
  10.197 -    /* only copy if curr_mac_addr is not a LUA */
  10.198 -    memcpy(xi->curr_mac_addr, xi->perm_mac_addr, ETH_ALEN);
  10.199 -  }
  10.200 -  XnFreeMem(xi->handle, tmp_string);
  10.201 -  FUNCTION_MSG("MAC address is %02X:%02X:%02X:%02X:%02X:%02X\n",
  10.202 -    xi->curr_mac_addr[0], xi->curr_mac_addr[1], xi->curr_mac_addr[2], 
  10.203 -    xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5]);
  10.204 -
  10.205 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "state", XenbusStateConnected);
  10.206 -
  10.207 -  for (i = 0; i <= 5 && xi->backend_state != XenbusStateConnected; i++) {
  10.208 -    FUNCTION_MSG("Waiting for XenbusStateConnected\n");
  10.209 -    KeWaitForSingleObject(&xi->backend_event, Executive, KernelMode, FALSE, NULL);
  10.210 -  }
  10.211 -  if (xi->backend_state != XenbusStateConnected) {
  10.212 -    FUNCTION_MSG("Backend state timeout\n");
  10.213 -    return STATUS_UNSUCCESSFUL;
  10.214 -  }
  10.215 -  XenNet_TxInit(xi);
  10.216 -  XenNet_RxInit(xi);
  10.217 -
  10.218 -  /* we don't set device_state = DEVICE_STATE_ACTIVE here - has to be done during init once ndis is ready */
  10.219 -  
  10.220 -  return STATUS_SUCCESS;
  10.221 -}
  10.222 -
  10.223 -static NTSTATUS
  10.224 -XenNet_Disconnect(PVOID context, BOOLEAN suspend) {
  10.225 -  struct xennet_info *xi = (struct xennet_info *)context;
  10.226 -  PFN_NUMBER pfn;
  10.227 -  NTSTATUS status;
  10.228 -
  10.229 -  if (xi->device_state != DEVICE_STATE_ACTIVE) {
  10.230 -    FUNCTION_MSG("state not DEVICE_STATE_ACTIVE, is %d instead\n", xi->device_state);
  10.231 -    FUNCTION_EXIT();
  10.232 -    return STATUS_SUCCESS;
  10.233 -  }
  10.234 -  xi->device_state = DEVICE_STATE_DISCONNECTING;
  10.235 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "state", XenbusStateClosing);
  10.236 -  while (xi->backend_state != XenbusStateClosing && xi->backend_state != XenbusStateClosed) {
  10.237 -    FUNCTION_MSG("Waiting for XenbusStateClosing/Closed\n");
  10.238 -    KeWaitForSingleObject(&xi->backend_event, Executive, KernelMode, FALSE, NULL);
  10.239 -  }
  10.240 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "state", XenbusStateClosed);
  10.241 -  while (xi->backend_state != XenbusStateClosed) {
  10.242 -    FUNCTION_MSG("Waiting for XenbusStateClosed\n");
  10.243 -    KeWaitForSingleObject(&xi->backend_event, Executive, KernelMode, FALSE, NULL);
  10.244 -  }
  10.245 -  XnUnbindEvent(xi->handle, xi->event_channel);
  10.246 -  KeFlushQueuedDpcs();
  10.247 -  XenNet_TxShutdown(xi);
  10.248 -  XenNet_RxShutdown(xi);
  10.249 -  pfn = MmGetPhysicalAddress(xi->rx_sring).QuadPart >> PAGE_SHIFT;
  10.250 -  XnEndAccess(xi->handle, xi->rx_sring_gref, FALSE, XENNET_POOL_TAG);
  10.251 -  ExFreePoolWithTag(xi->rx_sring, XENNET_POOL_TAG);
  10.252 -  pfn = MmGetPhysicalAddress(xi->tx_sring).QuadPart >> PAGE_SHIFT;
  10.253 -  XnEndAccess(xi->handle, xi->tx_sring_gref, FALSE, XENNET_POOL_TAG);
  10.254 -  ExFreePoolWithTag(xi->tx_sring, XENNET_POOL_TAG);
  10.255 -  if (!suspend) {
  10.256 -    XnCloseDevice(xi->handle);
  10.257 -  }
  10.258 -  xi->device_state = DEVICE_STATE_DISCONNECTED;
  10.259 -  return STATUS_SUCCESS;
  10.260 -};
  10.261 -
  10.262 -static VOID
  10.263 -XenNet_DeviceCallback(PVOID context, ULONG callback_type, PVOID value) {
  10.264 -  struct xennet_info *xi = (struct xennet_info *)context;
  10.265 -  ULONG state;
  10.266 -  
  10.267 -  FUNCTION_ENTER();
  10.268 -  switch (callback_type) {
  10.269 -  case XN_DEVICE_CALLBACK_BACKEND_STATE:
  10.270 -    state = (ULONG)(ULONG_PTR)value;
  10.271 -    if (state == xi->backend_state) {
  10.272 -      FUNCTION_MSG("same state %d\n", state);
  10.273 -      FUNCTION_EXIT();
  10.274 -    }
  10.275 -    FUNCTION_MSG("XenBusState = %d -> %d\n", xi->backend_state, state);
  10.276 -    xi->backend_state = state;
  10.277 -    KeSetEvent(&xi->backend_event, 0, FALSE);
  10.278 -    break;
  10.279 -  case XN_DEVICE_CALLBACK_SUSPEND:
  10.280 -    FUNCTION_MSG("XN_DEVICE_CALLBACK_SUSPEND");
  10.281 -    XenNet_Disconnect(xi, TRUE);
  10.282 -    break;
  10.283 -  case XN_DEVICE_CALLBACK_RESUME:
  10.284 -    FUNCTION_MSG("XN_DEVICE_CALLBACK_RESUME");
  10.285 -    XenNet_Connect(xi, TRUE);
  10.286 -    xi->device_state = DEVICE_STATE_ACTIVE;
  10.287 -    KeInsertQueueDpc(&xi->rxtx_dpc, NULL, NULL);
  10.288 -    break;
  10.289 -  }
  10.290 -  FUNCTION_EXIT();
  10.291 -}
  10.292 -
  10.293 -// Called at PASSIVE_LEVEL
  10.294 -static NDIS_STATUS
  10.295 -XenNet_Initialize(NDIS_HANDLE adapter_handle, NDIS_HANDLE driver_context, PNDIS_MINIPORT_INIT_PARAMETERS init_parameters)
  10.296 -{
  10.297 -  NDIS_STATUS status;
  10.298 -  struct xennet_info *xi = NULL;
  10.299 -  NDIS_HANDLE config_handle;
  10.300 -  NDIS_STRING config_param_name;
  10.301 -  NDIS_CONFIGURATION_OBJECT config_object;
  10.302 -  PNDIS_CONFIGURATION_PARAMETER config_param;
  10.303 -  //PNDIS_MINIPORT_ADAPTER_ATTRIBUTES adapter_attributes;
  10.304 -  ULONG i;
  10.305 -  ULONG length;
  10.306 -  PVOID network_address;
  10.307 -  UINT network_address_length;
  10.308 -  NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES registration_attributes;
  10.309 -  NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES general_attributes;
  10.310 -  NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES offload_attributes;
  10.311 -  NDIS_OFFLOAD df_offload, hw_offload;
  10.312 -  NDIS_TCP_CONNECTION_OFFLOAD df_conn_offload, hw_conn_offload;
  10.313 -  static NDIS_OID *supported_oids;
  10.314 -
  10.315 -  UNREFERENCED_PARAMETER(driver_context);
  10.316 -  UNREFERENCED_PARAMETER(init_parameters);
  10.317 -
  10.318 -  FUNCTION_ENTER();
  10.319 -
  10.320 -  /* Alloc memory for adapter private info */
  10.321 -  status = NdisAllocateMemoryWithTag((PVOID)&xi, sizeof(*xi), XENNET_POOL_TAG);
  10.322 -  if (!NT_SUCCESS(status))  {
  10.323 -    FUNCTION_MSG("NdisAllocateMemoryWithTag failed with 0x%x\n", status);
  10.324 -    status = NDIS_STATUS_RESOURCES;
  10.325 -    goto err;
  10.326 -  }
  10.327 -  RtlZeroMemory(xi, sizeof(*xi));
  10.328 -  xi->adapter_handle = adapter_handle;
  10.329 -  xi->device_state = DEVICE_STATE_INITIALISING;
  10.330 -  NdisMGetDeviceProperty(xi->adapter_handle, &xi->pdo, &xi->fdo,
  10.331 -    &xi->lower_do, NULL, NULL);
  10.332 -  KeInitializeEvent(&xi->backend_event, SynchronizationEvent, FALSE);
  10.333 -
  10.334 -  xi->rx_target     = RX_DFL_MIN_TARGET;
  10.335 -  xi->rx_min_target = RX_DFL_MIN_TARGET;
  10.336 -  xi->rx_max_target = RX_MAX_TARGET;
  10.337 -  
  10.338 -  xi->multicast_list_size = 0;
  10.339 -  xi->current_lookahead = MIN_LOOKAHEAD_LENGTH;
  10.340 -
  10.341 -  xi->stats.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
  10.342 -  xi->stats.Header.Revision = NDIS_STATISTICS_INFO_REVISION_1;
  10.343 -  xi->stats.Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1;
  10.344 -  xi->stats.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED
  10.345 -    | NDIS_STATISTICS_RCV_OK_SUPPORTED
  10.346 -    | NDIS_STATISTICS_XMIT_ERROR_SUPPORTED
  10.347 -    | NDIS_STATISTICS_RCV_ERROR_SUPPORTED
  10.348 -    | NDIS_STATISTICS_RCV_NO_BUFFER_SUPPORTED
  10.349 -    | NDIS_STATISTICS_DIRECTED_BYTES_XMIT_SUPPORTED
  10.350 -    | NDIS_STATISTICS_DIRECTED_FRAMES_XMIT_SUPPORTED
  10.351 -    | NDIS_STATISTICS_MULTICAST_BYTES_XMIT_SUPPORTED
  10.352 -    | NDIS_STATISTICS_MULTICAST_FRAMES_XMIT_SUPPORTED
  10.353 -    | NDIS_STATISTICS_BROADCAST_BYTES_XMIT_SUPPORTED
  10.354 -    | NDIS_STATISTICS_BROADCAST_FRAMES_XMIT_SUPPORTED
  10.355 -    | NDIS_STATISTICS_DIRECTED_BYTES_RCV_SUPPORTED
  10.356 -    | NDIS_STATISTICS_DIRECTED_FRAMES_RCV_SUPPORTED
  10.357 -    | NDIS_STATISTICS_MULTICAST_BYTES_RCV_SUPPORTED
  10.358 -    | NDIS_STATISTICS_MULTICAST_FRAMES_RCV_SUPPORTED
  10.359 -    | NDIS_STATISTICS_BROADCAST_BYTES_RCV_SUPPORTED
  10.360 -    | NDIS_STATISTICS_BROADCAST_FRAMES_RCV_SUPPORTED
  10.361 -    | NDIS_STATISTICS_RCV_CRC_ERROR_SUPPORTED
  10.362 -    | NDIS_STATISTICS_TRANSMIT_QUEUE_LENGTH_SUPPORTED
  10.363 -    | NDIS_STATISTICS_BYTES_RCV_SUPPORTED
  10.364 -    | NDIS_STATISTICS_BYTES_XMIT_SUPPORTED
  10.365 -    | NDIS_STATISTICS_RCV_DISCARDS_SUPPORTED
  10.366 -    | NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED
  10.367 -    | NDIS_STATISTICS_XMIT_DISCARDS_SUPPORTED;
  10.368 -
  10.369 -  KeInitializeDpc(&xi->rxtx_dpc, XenNet_RxTxDpc, xi);
  10.370 -
  10.371 -  xi->packet_filter = 0;
  10.372 -
  10.373 -  status = IoGetDeviceProperty(xi->pdo, DevicePropertyDeviceDescription,
  10.374 -    NAME_SIZE, xi->dev_desc, &length);
  10.375 -  if (!NT_SUCCESS(status)) {
  10.376 -    KdPrint(("IoGetDeviceProperty failed with 0x%x\n", status));
  10.377 -    status = NDIS_STATUS_FAILURE;
  10.378 -    goto err;
  10.379 -  }
  10.380 -
  10.381 -  //xi->power_state = NdisDeviceStateD0;
  10.382 -  //xi->power_workitem = IoAllocateWorkItem(xi->fdo);
  10.383 -
  10.384 -  config_object.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT);
  10.385 -  config_object.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
  10.386 -  config_object.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
  10.387 -  config_object.NdisHandle = xi->adapter_handle;
  10.388 -  config_object.Flags = 0;
  10.389 -
  10.390 -  status = NdisOpenConfigurationEx(&config_object, &config_handle);
  10.391 -  if (!NT_SUCCESS(status)) {
  10.392 -    FUNCTION_MSG("Could not open config in registry (%08x)\n", status);
  10.393 -    status = NDIS_STATUS_RESOURCES;
  10.394 -    goto err;
  10.395 -  }
  10.396 -
  10.397 -  NdisInitUnicodeString(&config_param_name, L"ScatterGather");
  10.398 -  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  10.399 -  if (!NT_SUCCESS(status))
  10.400 -  {
  10.401 -    FUNCTION_MSG("Could not read ScatterGather value (%08x)\n", status);
  10.402 -    xi->frontend_sg_supported = TRUE;
  10.403 -  } else {
  10.404 -    FUNCTION_MSG("ScatterGather = %d\n", config_param->ParameterData.IntegerData);
  10.405 -    xi->frontend_sg_supported = !!config_param->ParameterData.IntegerData;
  10.406 -  }
  10.407 -  if (xi->frontend_sg_supported && ndis_os_minor_version < 1) {
  10.408 -    FUNCTION_MSG("No support for SG with NDIS 6.0, disabled\n");
  10.409 -    xi->frontend_sg_supported = FALSE;
  10.410 -  }
  10.411 -  
  10.412 -  NdisInitUnicodeString(&config_param_name, L"LargeSendOffload");
  10.413 -  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  10.414 -  if (!NT_SUCCESS(status)) {
  10.415 -    FUNCTION_MSG("Could not read LargeSendOffload value (%08x)\n", status);
  10.416 -    xi->frontend_gso_value = 0;
  10.417 -  } else {
  10.418 -    FUNCTION_MSG("LargeSendOffload = %d\n", config_param->ParameterData.IntegerData);
  10.419 -    xi->frontend_gso_value = config_param->ParameterData.IntegerData;
  10.420 -    if (xi->frontend_gso_value > 61440) {
  10.421 -      xi->frontend_gso_value = 61440;
  10.422 -      FUNCTION_MSG("  (clipped to %d)\n", xi->frontend_gso_value);
  10.423 -    }
  10.424 -    if (!xi->frontend_sg_supported && xi->frontend_gso_value > PAGE_SIZE - MAX_PKT_HEADER_LENGTH) {
  10.425 -      /* without SG, GSO can be a maximum of PAGE_SIZE - MAX_PKT_HEADER_LENGTH */
  10.426 -      xi->frontend_gso_value = min(xi->frontend_gso_value, PAGE_SIZE - MAX_PKT_HEADER_LENGTH);
  10.427 -      FUNCTION_MSG("  (clipped to %d with sg disabled)\n", xi->frontend_gso_value);
  10.428 -    }
  10.429 -  }
  10.430 -  if (xi->frontend_sg_supported && ndis_os_minor_version < 1) {
  10.431 -    FUNCTION_MSG("No support for GSO with NDIS 6.0, disabled\n");
  10.432 -    xi->frontend_gso_value = 0;
  10.433 -  }
  10.434 -
  10.435 -  NdisInitUnicodeString(&config_param_name, L"LargeSendOffloadRxSplitMTU");
  10.436 -  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  10.437 -  if (!NT_SUCCESS(status)) {
  10.438 -    FUNCTION_MSG("Could not read LargeSendOffload value (%08x)\n", status);
  10.439 -    xi->frontend_gso_rx_split_type = RX_LSO_SPLIT_HALF;
  10.440 -  } else {
  10.441 -    FUNCTION_MSG("LargeSendOffloadRxSplitMTU = %d\n", config_param->ParameterData.IntegerData);
  10.442 -    switch (config_param->ParameterData.IntegerData) {
  10.443 -    case RX_LSO_SPLIT_MSS:
  10.444 -    case RX_LSO_SPLIT_HALF:
  10.445 -    case RX_LSO_SPLIT_NONE:
  10.446 -      xi->frontend_gso_rx_split_type = config_param->ParameterData.IntegerData;
  10.447 -      break;
  10.448 -    default:
  10.449 -      xi->frontend_gso_rx_split_type = RX_LSO_SPLIT_HALF;
  10.450 -      break;
  10.451 -    }
  10.452 -  }
  10.453 -
  10.454 -  NdisInitUnicodeString(&config_param_name, L"ChecksumOffload");
  10.455 -  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  10.456 -  if (!NT_SUCCESS(status)) {
  10.457 -    FUNCTION_MSG("Could not read ChecksumOffload value (%08x)\n", status);
  10.458 -    xi->frontend_csum_supported = TRUE;
  10.459 -  } else {
  10.460 -    FUNCTION_MSG("ChecksumOffload = %d\n", config_param->ParameterData.IntegerData);
  10.461 -    xi->frontend_csum_supported = !!config_param->ParameterData.IntegerData;
  10.462 -  }
  10.463 -
  10.464 -  NdisInitUnicodeString(&config_param_name, L"MTU");
  10.465 -  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);  
  10.466 -  if (!NT_SUCCESS(status)) {
  10.467 -    FUNCTION_MSG("Could not read MTU value (%08x)\n", status);
  10.468 -    xi->frontend_mtu_value = 1500;
  10.469 -  } else {
  10.470 -    FUNCTION_MSG("MTU = %d\n", config_param->ParameterData.IntegerData);
  10.471 -    xi->frontend_mtu_value = config_param->ParameterData.IntegerData;
  10.472 -  }
  10.473 -  
  10.474 -  NdisReadNetworkAddress(&status, &network_address, &network_address_length, config_handle);
  10.475 -  if (!NT_SUCCESS(status) || network_address_length != ETH_ALEN || ((((PUCHAR)network_address)[0] & 0x03) != 0x02)) {
  10.476 -    FUNCTION_MSG("Could not read registry NetworkAddress value (%08x) or value is invalid\n", status);
  10.477 -    memset(xi->curr_mac_addr, 0, ETH_ALEN);
  10.478 -  } else {
  10.479 -    memcpy(xi->curr_mac_addr, network_address, ETH_ALEN);
  10.480 -    FUNCTION_MSG("Set MAC address from registry to %02X:%02X:%02X:%02X:%02X:%02X\n",
  10.481 -      xi->curr_mac_addr[0], xi->curr_mac_addr[1], xi->curr_mac_addr[2], 
  10.482 -      xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5]);
  10.483 -  }
  10.484 -
  10.485 -  NdisCloseConfiguration(config_handle);
  10.486 -
  10.487 -  XenNet_Connect(xi, FALSE);
  10.488 -
  10.489 -  if (!xi->backend_sg_supported)
  10.490 -    xi->backend_gso_value = min(xi->backend_gso_value, PAGE_SIZE - MAX_PKT_HEADER_LENGTH);
  10.491 -
  10.492 -  xi->current_sg_supported = xi->frontend_sg_supported && xi->backend_sg_supported;
  10.493 -  xi->current_csum_supported = xi->frontend_csum_supported && xi->backend_csum_supported;
  10.494 -  xi->current_gso_value = min(xi->backend_gso_value, xi->backend_gso_value);
  10.495 -  xi->current_mtu_value = xi->frontend_mtu_value;
  10.496 -  xi->current_gso_rx_split_type = xi->frontend_gso_rx_split_type;
  10.497 -  
  10.498 -  xi->config_max_pkt_size = max(xi->current_mtu_value + XN_HDR_SIZE, xi->current_gso_value + XN_HDR_SIZE);
  10.499 -    
  10.500 -  registration_attributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
  10.501 -  registration_attributes.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
  10.502 -  registration_attributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
  10.503 -  registration_attributes.MiniportAdapterContext = xi;
  10.504 -  registration_attributes.AttributeFlags = 0;
  10.505 -  registration_attributes.AttributeFlags |= NDIS_MINIPORT_ATTRIBUTES_HARDWARE_DEVICE;
  10.506 -  registration_attributes.AttributeFlags |= NDIS_MINIPORT_ATTRIBUTES_SURPRISE_REMOVE_OK;
  10.507 -  registration_attributes.CheckForHangTimeInSeconds = 0; /* use default */
  10.508 -  registration_attributes.InterfaceType = NdisInterfacePNPBus;
  10.509 -  status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&registration_attributes);
  10.510 -  if (!NT_SUCCESS(status)) {
  10.511 -    FUNCTION_MSG("NdisMSetMiniportAttributes(registration) failed (%08x)\n", status);
  10.512 -    goto err;
  10.513 -  }
  10.514 -  
  10.515 -  general_attributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
  10.516 -  general_attributes.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1; /* revision 2 is NDIS 6.2 */
  10.517 -  general_attributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
  10.518 -  general_attributes.Flags = 0;
  10.519 -  general_attributes.MediaType = NdisMedium802_3;
  10.520 -  general_attributes.PhysicalMediumType = NdisPhysicalMediumOther;
  10.521 -  general_attributes.MtuSize = xi->current_mtu_value;
  10.522 -  general_attributes.MaxXmitLinkSpeed = MAX_LINK_SPEED;
  10.523 -  general_attributes.XmitLinkSpeed = MAX_LINK_SPEED;
  10.524 -  general_attributes.MaxRcvLinkSpeed = MAX_LINK_SPEED;
  10.525 -  general_attributes.RcvLinkSpeed = MAX_LINK_SPEED;
  10.526 -  general_attributes.MediaConnectState = MediaConnectStateConnected;
  10.527 -  general_attributes.MediaDuplexState = MediaDuplexStateFull;
  10.528 -  general_attributes.LookaheadSize = xi->current_lookahead;
  10.529 -  general_attributes.PowerManagementCapabilities = NULL;
  10.530 -  general_attributes.MacOptions = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | 
  10.531 -        NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
  10.532 -        NDIS_MAC_OPTION_NO_LOOPBACK;
  10.533 -  general_attributes.SupportedPacketFilters = SUPPORTED_PACKET_FILTERS;
  10.534 -  general_attributes.MaxMulticastListSize = MULTICAST_LIST_MAX_SIZE;
  10.535 -  general_attributes.MacAddressLength = 6;
  10.536 -  NdisMoveMemory(general_attributes.PermanentMacAddress, xi->perm_mac_addr, general_attributes.MacAddressLength);
  10.537 -  NdisMoveMemory(general_attributes.CurrentMacAddress, xi->curr_mac_addr, general_attributes.MacAddressLength);
  10.538 -  general_attributes.RecvScaleCapabilities = NULL; /* we do want to support this soon */
  10.539 -  general_attributes.AccessType = NET_IF_ACCESS_BROADCAST;
  10.540 -  general_attributes.DirectionType = NET_IF_DIRECTION_SENDRECEIVE;
  10.541 -  general_attributes.ConnectionType = NET_IF_CONNECTION_DEDICATED;
  10.542 -  general_attributes.IfType = IF_TYPE_ETHERNET_CSMACD;
  10.543 -  general_attributes.IfConnectorPresent = TRUE;
  10.544 -  general_attributes.SupportedStatistics = xi->stats.SupportedStatistics;
  10.545 -  general_attributes.SupportedPauseFunctions = NdisPauseFunctionsUnsupported;
  10.546 -  general_attributes.DataBackFillSize = 0; // see NdisRetreatNetBufferDataStart
  10.547 -  general_attributes.ContextBackFillSize = 0; // ?? NFI ??
  10.548 -  
  10.549 -  for (i = 0; xennet_oids[i].oid; i++);
  10.550 -  
  10.551 -  status = NdisAllocateMemoryWithTag((PVOID)&supported_oids, sizeof(NDIS_OID) * i, XENNET_POOL_TAG);
  10.552 -  if (!NT_SUCCESS(status)) {
  10.553 -    FUNCTION_MSG("NdisAllocateMemoryWithTag failed with 0x%x\n", status);
  10.554 -    status = NDIS_STATUS_RESOURCES;
  10.555 -    goto err;
  10.556 -  }
  10.557 -
  10.558 -  for (i = 0; xennet_oids[i].oid; i++) {
  10.559 -    supported_oids[i] = xennet_oids[i].oid;
  10.560 -    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);
  10.561 -  }
  10.562 -  general_attributes.SupportedOidList = supported_oids;
  10.563 -  general_attributes.SupportedOidListLength = sizeof(NDIS_OID) * i;
  10.564 -  general_attributes.AutoNegotiationFlags = NDIS_LINK_STATE_XMIT_LINK_SPEED_AUTO_NEGOTIATED
  10.565 -    | NDIS_LINK_STATE_RCV_LINK_SPEED_AUTO_NEGOTIATED
  10.566 -    | NDIS_LINK_STATE_DUPLEX_AUTO_NEGOTIATED;
  10.567 -  //general_attributes.PowerManagementCapabilitiesEx = NULL; // >= 6.20
  10.568 -  status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&general_attributes);
  10.569 -  if (!NT_SUCCESS(status)) {
  10.570 -    FUNCTION_MSG("NdisMSetMiniportAttributes(general) failed (%08x)\n", status);
  10.571 -    goto err;
  10.572 -  }
  10.573 -  NdisFreeMemory(supported_oids, 0, 0);
  10.574 -    
  10.575 -  /* this is the initial offload state */
  10.576 -  RtlZeroMemory(&df_offload, sizeof(df_offload));
  10.577 -  df_offload.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
  10.578 -  df_offload.Header.Revision = NDIS_OFFLOAD_REVISION_1; // revision 2 does exist
  10.579 -  df_offload.Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;
  10.580 -  /* this is the supported offload state */
  10.581 -  RtlZeroMemory(&hw_offload, sizeof(hw_offload));
  10.582 -  hw_offload.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
  10.583 -  hw_offload.Header.Revision = NDIS_OFFLOAD_REVISION_1; // revision 2 does exist
  10.584 -  hw_offload.Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;
  10.585 -  if (xi->current_csum_supported)
  10.586 -  {
  10.587 -    df_offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
  10.588 -    df_offload.Checksum.IPv4Transmit.IpOptionsSupported = NDIS_OFFLOAD_SET_ON;
  10.589 -    df_offload.Checksum.IPv4Transmit.TcpOptionsSupported = NDIS_OFFLOAD_SET_ON;
  10.590 -    df_offload.Checksum.IPv4Transmit.TcpChecksum = NDIS_OFFLOAD_SET_ON;
  10.591 -    df_offload.Checksum.IPv4Transmit.UdpChecksum = NDIS_OFFLOAD_SET_ON;
  10.592 -    df_offload.Checksum.IPv4Transmit.IpChecksum = NDIS_OFFLOAD_SET_ON;
  10.593 -    df_offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
  10.594 -    df_offload.Checksum.IPv4Receive.IpOptionsSupported = NDIS_OFFLOAD_SET_ON;
  10.595 -    df_offload.Checksum.IPv4Receive.TcpOptionsSupported = NDIS_OFFLOAD_SET_ON;
  10.596 -    df_offload.Checksum.IPv4Receive.TcpChecksum = NDIS_OFFLOAD_SET_ON;
  10.597 -    df_offload.Checksum.IPv4Receive.UdpChecksum = NDIS_OFFLOAD_SET_ON;
  10.598 -    df_offload.Checksum.IPv4Receive.IpChecksum = NDIS_OFFLOAD_SET_ON;
  10.599 -    /* offload.Checksum.IPv6Transmit is not supported */
  10.600 -    /* offload.Checksum.IPv6Receive is not supported */
  10.601 -    hw_offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
  10.602 -    hw_offload.Checksum.IPv4Transmit.IpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;
  10.603 -    hw_offload.Checksum.IPv4Transmit.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;
  10.604 -    hw_offload.Checksum.IPv4Transmit.TcpChecksum = NDIS_OFFLOAD_SUPPORTED;
  10.605 -    hw_offload.Checksum.IPv4Transmit.UdpChecksum = NDIS_OFFLOAD_SUPPORTED;
  10.606 -    hw_offload.Checksum.IPv4Transmit.IpChecksum = NDIS_OFFLOAD_SUPPORTED;
  10.607 -    hw_offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
  10.608 -    hw_offload.Checksum.IPv4Receive.IpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;
  10.609 -    hw_offload.Checksum.IPv4Receive.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;
  10.610 -    hw_offload.Checksum.IPv4Receive.TcpChecksum = NDIS_OFFLOAD_SUPPORTED;
  10.611 -    hw_offload.Checksum.IPv4Receive.UdpChecksum = NDIS_OFFLOAD_SUPPORTED;
  10.612 -    hw_offload.Checksum.IPv4Receive.IpChecksum = NDIS_OFFLOAD_SUPPORTED;
  10.613 -    /* hw_offload.Checksum.IPv6Transmit is not supported */
  10.614 -    /* hw_offload.Checksum.IPv6Receive is not supported */
  10.615 -  }
  10.616 -  if (xi->current_gso_value)
  10.617 -  {
  10.618 -    hw_offload.LsoV1.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
  10.619 -    hw_offload.LsoV1.IPv4.MaxOffLoadSize = xi->current_gso_value;
  10.620 -    hw_offload.LsoV1.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
  10.621 -    hw_offload.LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */
  10.622 -    hw_offload.LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */
  10.623 -    hw_offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
  10.624 -    hw_offload.LsoV2.IPv4.MaxOffLoadSize = xi->current_gso_value;
  10.625 -    hw_offload.LsoV2.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
  10.626 -    /* hw_offload.LsoV2.IPv6 is not supported */
  10.627 -    df_offload.LsoV1.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
  10.628 -    df_offload.LsoV1.IPv4.MaxOffLoadSize = xi->current_gso_value;
  10.629 -    df_offload.LsoV1.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
  10.630 -    df_offload.LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */
  10.631 -    df_offload.LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */
  10.632 -    df_offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
  10.633 -    df_offload.LsoV2.IPv4.MaxOffLoadSize = xi->current_gso_value;
  10.634 -    df_offload.LsoV2.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
  10.635 -    /* df_offload.LsoV2.IPv6 is not supported */
  10.636 -  }
  10.637 -  /* hw_offload.IPsecV1 is not supported */
  10.638 -  /* hw_offload.IPsecV2 is not supported */
  10.639 -  /* df_offload.IPsecV1 is not supported */
  10.640 -  /* df_offload.IPsecV2 is not supported */
  10.641 -  hw_offload.Flags = 0;
  10.642 -  df_offload.Flags = 0;
  10.643 -  
  10.644 -  RtlZeroMemory(&df_conn_offload, sizeof(df_conn_offload));
  10.645 -  df_conn_offload.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
  10.646 -  df_conn_offload.Header.Revision = NDIS_TCP_CONNECTION_OFFLOAD_REVISION_1;
  10.647 -  df_conn_offload.Header.Size = NDIS_SIZEOF_TCP_CONNECTION_OFFLOAD_REVISION_1;
  10.648 -
  10.649 -  RtlZeroMemory(&hw_conn_offload, sizeof(hw_conn_offload));
  10.650 -  hw_conn_offload.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
  10.651 -  hw_conn_offload.Header.Revision = NDIS_TCP_CONNECTION_OFFLOAD_REVISION_1;
  10.652 -  hw_conn_offload.Header.Size = NDIS_SIZEOF_TCP_CONNECTION_OFFLOAD_REVISION_1;
  10.653 -  
  10.654 -  offload_attributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES;
  10.655 -  offload_attributes.Header.Revision = NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
  10.656 -  offload_attributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
  10.657 -  offload_attributes.DefaultOffloadConfiguration = &df_offload;
  10.658 -  offload_attributes.HardwareOffloadCapabilities = &hw_offload;
  10.659 -  offload_attributes.DefaultTcpConnectionOffloadConfiguration = &df_conn_offload;
  10.660 -  offload_attributes.TcpConnectionOffloadHardwareCapabilities  = &hw_conn_offload;
  10.661 -  status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&offload_attributes);
  10.662 -  if (!NT_SUCCESS(status)) {
  10.663 -    FUNCTION_MSG("NdisMSetMiniportAttributes(offload) failed (%08x)\n", status);
  10.664 -    goto err;
  10.665 -  }
  10.666 -  
  10.667 -  #if 0
  10.668 -  if (ndis_os_minor_version >= 1) {
  10.669 -    NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES hw_assist_attributes;
  10.670 -    NDIS_HD_SPLIT_ATTRIBUTES hd_split_attributes;
  10.671 -    
  10.672 -    RtlZeroMemory(&hd_split_attributes, sizeof(hd_split_attributes));
  10.673 -    hd_split_attributes.Header.Type = NDIS_OBJECT_TYPE_HD_SPLIT_ATTRIBUTES;
  10.674 -    hd_split_attributes.Header.Revision = NDIS_HD_SPLIT_ATTRIBUTES_REVISION_1;
  10.675 -    hd_split_attributes.Header.Size = NDIS_SIZEOF_HD_SPLIT_ATTRIBUTES_REVISION_1;
  10.676 -    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;
  10.677 -    hd_split_attributes.CurrentCapabilities = hd_split_attributes.HardwareCapabilities;
  10.678 -    /* the other members are set on output */
  10.679 -    
  10.680 -    RtlZeroMemory(&hw_assist_attributes, sizeof(hw_assist_attributes));
  10.681 -    hw_assist_attributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES;
  10.682 -    hw_assist_attributes.Header.Revision = NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;
  10.683 -    hw_assist_attributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;
  10.684 -    hw_assist_attributes.HDSplitAttributes = &hd_split_attributes;
  10.685 -    status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&hw_assist_attributes);
  10.686 -    if (!NT_SUCCESS(status))
  10.687 -    {
  10.688 -      FUNCTION_MSG("NdisMSetMiniportAttributes(hw_assist) failed (%08x)\n", status);
  10.689 -      goto err;
  10.690 -    }
  10.691 -    FUNCTION_MSG("HW Split enabled\n");
  10.692 -    FUNCTION_MSG(" HDSplitFlags = %08x\n", hd_split_attributes.HDSplitFlags);
  10.693 -    FUNCTION_MSG(" BackfillSize = %d\n", hd_split_attributes.BackfillSize);
  10.694 -    FUNCTION_MSG(" MaxHeaderSize = %d\n", hd_split_attributes.MaxHeaderSize);
  10.695 -    //what about backfill here?
  10.696 -  }
  10.697 -  #endif
  10.698 -  xi->device_state = DEVICE_STATE_ACTIVE;
  10.699 -  FUNCTION_EXIT();
  10.700 -  return NDIS_STATUS_SUCCESS;
  10.701 -  
  10.702 -err:
  10.703 -  if (xi) {
  10.704 -    NdisFreeMemory(xi, 0, 0);
  10.705 -  }
  10.706 -  FUNCTION_EXIT_STATUS(status);
  10.707 -
  10.708 -  return status;
  10.709 -}
  10.710 -
  10.711 -static VOID
  10.712 -XenNet_DevicePnPEventNotify(NDIS_HANDLE adapter_context, PNET_DEVICE_PNP_EVENT pnp_event)
  10.713 -{
  10.714 -  UNREFERENCED_PARAMETER(adapter_context);
  10.715 -
  10.716 -  FUNCTION_ENTER();
  10.717 -  switch (pnp_event->DevicePnPEvent)
  10.718 -  {
  10.719 -  case NdisDevicePnPEventSurpriseRemoved:
  10.720 -    FUNCTION_MSG("NdisDevicePnPEventSurpriseRemoved\n");
  10.721 -    break;
  10.722 -  case NdisDevicePnPEventPowerProfileChanged :
  10.723 -    FUNCTION_MSG("NdisDevicePnPEventPowerProfileChanged\n");
  10.724 -    break;
  10.725 -  default:
  10.726 -    FUNCTION_MSG("NdisDevicePnPEvent%d\n", pnp_event->DevicePnPEvent);
  10.727 -    break;
  10.728 -  }
  10.729 -  FUNCTION_EXIT();
  10.730 -}
  10.731 -
  10.732 -/* called at <= HIGH_IRQL, or PASSIVE_LEVEL, depending on shutdown_action */
  10.733 -VOID
  10.734 -XenNet_Shutdown(NDIS_HANDLE adapter_context, NDIS_SHUTDOWN_ACTION shutdown_action)
  10.735 -{
  10.736 -  UNREFERENCED_PARAMETER(adapter_context);
  10.737 -  UNREFERENCED_PARAMETER(shutdown_action);
  10.738 -
  10.739 -  FUNCTION_ENTER();
  10.740 -  FUNCTION_EXIT();
  10.741 -}
  10.742 -
  10.743 -static BOOLEAN
  10.744 -XenNet_CheckForHang(NDIS_HANDLE adapter_context)
  10.745 -{
  10.746 -  UNREFERENCED_PARAMETER(adapter_context);
  10.747 -
  10.748 -  //FUNCTION_ENTER();
  10.749 -  //FUNCTION_EXIT();
  10.750 -  return FALSE;
  10.751 -}
  10.752 -
  10.753 -/* Opposite of XenNet_Init */
  10.754 -static VOID
  10.755 -XenNet_Halt(NDIS_HANDLE adapter_context, NDIS_HALT_ACTION halt_action)
  10.756 -{
  10.757 -  struct xennet_info *xi = adapter_context;
  10.758 -  UNREFERENCED_PARAMETER(halt_action);
  10.759 -
  10.760 -  FUNCTION_ENTER();
  10.761 -  XenNet_Disconnect(xi, FALSE);
  10.762 -  NdisFreeMemory(xi, 0, 0);
  10.763 -
  10.764 -  FUNCTION_EXIT();
  10.765 -}
  10.766 -
  10.767 -static NDIS_STATUS 
  10.768 -XenNet_Reset(NDIS_HANDLE adapter_context, PBOOLEAN addressing_reset)
  10.769 -{
  10.770 -  UNREFERENCED_PARAMETER(adapter_context);
  10.771 -
  10.772 -  FUNCTION_ENTER();
  10.773 -  *addressing_reset = FALSE;
  10.774 -  FUNCTION_EXIT();
  10.775 -  return NDIS_STATUS_SUCCESS;
  10.776 -}
  10.777 -
  10.778 -/* called at PASSIVE_LEVEL */
  10.779 -static NDIS_STATUS
  10.780 -XenNet_Pause(NDIS_HANDLE adapter_context, PNDIS_MINIPORT_PAUSE_PARAMETERS pause_parameters)
  10.781 -{
  10.782 -  UNREFERENCED_PARAMETER(adapter_context);
  10.783 -  UNREFERENCED_PARAMETER(pause_parameters);
  10.784 -  FUNCTION_ENTER();
  10.785 -  FUNCTION_EXIT();
  10.786 -  return STATUS_SUCCESS;
  10.787 -}
  10.788 -
  10.789 -/* called at PASSIVE_LEVEL */
  10.790 -static NDIS_STATUS
  10.791 -XenNet_Restart(NDIS_HANDLE adapter_context, PNDIS_MINIPORT_RESTART_PARAMETERS restart_parameters)
  10.792 -{
  10.793 -  UNREFERENCED_PARAMETER(adapter_context);
  10.794 -  UNREFERENCED_PARAMETER(restart_parameters);
  10.795 -  FUNCTION_ENTER();
  10.796 -  FUNCTION_EXIT();
  10.797 -  return STATUS_SUCCESS;
  10.798 -}
  10.799 -
  10.800 -static VOID
  10.801 -XenNet_Unload(PDRIVER_OBJECT driver_object)
  10.802 -{
  10.803 -  UNREFERENCED_PARAMETER(driver_object);
  10.804 -  FUNCTION_ENTER();
  10.805 -  NdisMDeregisterMiniportDriver(driver_handle);
  10.806 -  FUNCTION_EXIT();
  10.807 -}
  10.808 -
  10.809 -static NDIS_STATUS
  10.810 -XenNet_SetOptions(NDIS_HANDLE driver_handle, NDIS_HANDLE driver_context)
  10.811 -{
  10.812 -  UNREFERENCED_PARAMETER(driver_handle);
  10.813 -  UNREFERENCED_PARAMETER(driver_context);
  10.814 -  FUNCTION_ENTER();
  10.815 -  FUNCTION_EXIT();
  10.816 -  return STATUS_SUCCESS;
  10.817 -}
  10.818 -
  10.819 -NTSTATUS
  10.820 -DriverEntry(PDRIVER_OBJECT driver_object, PUNICODE_STRING registry_path)
  10.821 -{
  10.822 -  NTSTATUS status;  
  10.823 -  NDIS_MINIPORT_DRIVER_CHARACTERISTICS mini_chars;
  10.824 -  ULONG ndis_version;
  10.825 -  
  10.826 -  FUNCTION_ENTER();
  10.827 -
  10.828 -  ndis_version = NdisGetVersion();
  10.829 -  
  10.830 -  ndis_os_major_version = ndis_version >> 16;
  10.831 -  ndis_os_minor_version = ndis_version & 0xFFFF;
  10.832 -
  10.833 -  NdisZeroMemory(&mini_chars, sizeof(mini_chars));
  10.834 -
  10.835 -  mini_chars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS;
  10.836 -  
  10.837 -  if (ndis_os_minor_version < 1) {
  10.838 -    mini_chars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
  10.839 -    mini_chars.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
  10.840 -
  10.841 -    mini_chars.MajorNdisVersion = 6;
  10.842 -    mini_chars.MinorNdisVersion = 0;
  10.843 -  } else {
  10.844 -    mini_chars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
  10.845 -    mini_chars.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
  10.846 -    mini_chars.MajorNdisVersion = 6;
  10.847 -    mini_chars.MinorNdisVersion = 1;
  10.848 -  }
  10.849 -  mini_chars.MajorDriverVersion = VENDOR_DRIVER_VERSION_MAJOR;
  10.850 -  mini_chars.MinorDriverVersion = VENDOR_DRIVER_VERSION_MINOR;
  10.851 -
  10.852 -  FUNCTION_MSG("Driver MajorNdisVersion = %d, Driver MinorNdisVersion = %d\n", NDIS_MINIPORT_MAJOR_VERSION, NDIS_MINIPORT_MINOR_VERSION);
  10.853 -  FUNCTION_MSG("Windows MajorNdisVersion = %d, Windows MinorNdisVersion = %d\n", ndis_os_major_version, ndis_os_minor_version);
  10.854 -
  10.855 -  mini_chars.Flags = NDIS_WDM_DRIVER;
  10.856 -  
  10.857 -  mini_chars.SetOptionsHandler = XenNet_SetOptions;
  10.858 -  mini_chars.InitializeHandlerEx = XenNet_Initialize;
  10.859 -  mini_chars.HaltHandlerEx = XenNet_Halt;
  10.860 -  mini_chars.UnloadHandler = XenNet_Unload;
  10.861 -  mini_chars.PauseHandler = XenNet_Pause;
  10.862 -  mini_chars.RestartHandler = XenNet_Restart;
  10.863 -  mini_chars.CheckForHangHandlerEx = XenNet_CheckForHang;
  10.864 -  mini_chars.ResetHandlerEx = XenNet_Reset;
  10.865 -  mini_chars.DevicePnPEventNotifyHandler = XenNet_DevicePnPEventNotify;
  10.866 -  mini_chars.ShutdownHandlerEx = XenNet_Shutdown;
  10.867 -
  10.868 -  mini_chars.OidRequestHandler = XenNet_OidRequest;
  10.869 -  mini_chars.CancelOidRequestHandler = XenNet_CancelOidRequest;
  10.870 -  if (ndis_os_minor_version >= 1) {
  10.871 -    mini_chars.DirectOidRequestHandler = NULL;
  10.872 -    mini_chars.CancelDirectOidRequestHandler = NULL;
  10.873 -  }
  10.874 -
  10.875 -  mini_chars.SendNetBufferListsHandler = XenNet_SendNetBufferLists;
  10.876 -  mini_chars.CancelSendHandler = XenNet_CancelSend;
  10.877 -
  10.878 -  mini_chars.ReturnNetBufferListsHandler = XenNet_ReturnNetBufferLists;
  10.879 -
  10.880 -  status = NdisMRegisterMiniportDriver(driver_object, registry_path, NULL, &mini_chars, &driver_handle);
  10.881 -  if (!NT_SUCCESS(status))
  10.882 -  {
  10.883 -    FUNCTION_MSG("NdisMRegisterMiniportDriver failed, status = 0x%x\n", status);
  10.884 -    return status;
  10.885 -  }
  10.886 -
  10.887 -  FUNCTION_EXIT();
  10.888 -
  10.889 -  return status;
  10.890 -}
    11.1 --- a/xennet/xennet6.h	Sun Feb 10 23:12:03 2013 +1100
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,472 +0,0 @@
    11.4 -/*
    11.5 -PV Drivers for Windows Xen HVM Domains
    11.6 -Copyright (C) 2007 James Harper
    11.7 -Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
    11.8 -
    11.9 -This program is free software; you can redistribute it and/or
   11.10 -modify it under the terms of the GNU General Public License
   11.11 -as published by the Free Software Foundation; either version 2
   11.12 -of the License, or (at your option) any later version.
   11.13 -
   11.14 -This program is distributed in the hope that it will be useful,
   11.15 -but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.16 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11.17 -GNU General Public License for more details.
   11.18 -
   11.19 -You should have received a copy of the GNU General Public License
   11.20 -along with this program; if not, write to the Free Software
   11.21 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   11.22 -*/
   11.23 -
   11.24 -#pragma warning(disable: 4201)
   11.25 -#pragma warning(disable: 4214)
   11.26 -
   11.27 -#include <ntddk.h>
   11.28 -#include <wdm.h>
   11.29 -#define NDIS_MINIPORT_DRIVER 1
   11.30 -#define NDIS61_MINIPORT 1
   11.31 -#include <ndis.h>
   11.32 -#define NTSTRSAFE_LIB
   11.33 -#include <ntstrsafe.h>
   11.34 -#include <liblfds.h>
   11.35 -
   11.36 -#define VENDOR_DRIVER_VERSION_MAJOR 0
   11.37 -#define VENDOR_DRIVER_VERSION_MINOR 11
   11.38 -
   11.39 -#define MAX_LINK_SPEED 10000000000L; /* there is not really any theoretical maximum... */
   11.40 -
   11.41 -#define VENDOR_DRIVER_VERSION (((VENDOR_DRIVER_VERSION_MAJOR) << 16) | (VENDOR_DRIVER_VERSION_MINOR))
   11.42 -
   11.43 -#define __DRIVER_NAME "XenNet"
   11.44 -
   11.45 -#define NB_LIST_ENTRY_FIELD MiniportReserved[0] // TX (2 entries)
   11.46 -#define NB_FIRST_PB_FIELD MiniportReserved[0] // RX
   11.47 -#define NB_NBL_FIELD MiniportReserved[2] // TX
   11.48 -#define NB_LIST_ENTRY(_nb) (*(PLIST_ENTRY)&(_nb)->NB_LIST_ENTRY_FIELD)
   11.49 -#define NB_NBL(_nb) (*(PNET_BUFFER_LIST *)&(_nb)->NB_NBL_FIELD)
   11.50 -#define NB_FIRST_PB(_nb) (*(shared_buffer_t **)&(_nb)->NB_FIRST_PB_FIELD)
   11.51 -
   11.52 -#define NBL_REF_FIELD MiniportReserved[0] // TX
   11.53 -//#define NBL_LIST_ENTRY_FIELD MiniportReserved[0] // TX (2 entries) - overlaps with REF_FIELD
   11.54 -//#define NBL_PACKET_COUNT_FIELD MiniportReserved[0] // RX
   11.55 -//#define NBL_LAST_NB_FIELD MiniportReserved[1] // RX
   11.56 -#define NBL_REF(_nbl) (*(ULONG_PTR *)&(_nbl)->NBL_REF_FIELD)
   11.57 -//#define NBL_LIST_ENTRY(_nbl) (*(PLIST_ENTRY)&(_nbl)->NBL_LIST_ENTRY_FIELD)
   11.58 -//#define NBL_PACKET_COUNT(_nbl) (*(ULONG_PTR *)&(_nbl)->NBL_PACKET_COUNT_FIELD)
   11.59 -//#define NBL_LAST_NB(_nbl) (*(PNET_BUFFER *)&(_nbl)->NBL_LAST_NB_FIELD)
   11.60 -
   11.61 -#include <xen_windows.h>
   11.62 -#include <memory.h>
   11.63 -#include <grant_table.h>
   11.64 -#include <event_channel.h>
   11.65 -#include <hvm/params.h>
   11.66 -#include <hvm/hvm_op.h>
   11.67 -#include <xen_public.h>
   11.68 -#include <io/ring.h>
   11.69 -#include <io/netif.h>
   11.70 -#include <io/xenbus.h>
   11.71 -#include <stdlib.h>
   11.72 -#define XENNET_POOL_TAG (ULONG) 'XenN'
   11.73 -
   11.74 -/* Xen macros use these, so they need to be redefined to Win equivs */
   11.75 -#define wmb() KeMemoryBarrier()
   11.76 -#define mb() KeMemoryBarrier()
   11.77 -
   11.78 -#define GRANT_INVALID_REF 0
   11.79 -
   11.80 -#define NAME_SIZE 64
   11.81 -
   11.82 -#define ETH_ALEN 6
   11.83 -
   11.84 -/*
   11.85 -#define __NET_USHORT_BYTE_0(x) ((USHORT)(x & 0xFF))
   11.86 -#define __NET_USHORT_BYTE_1(x) ((USHORT)((PUCHAR)&x)[1] & 0xFF)
   11.87 -
   11.88 -#define GET_NET_USHORT(x) ((__NET_USHORT_BYTE_0(x) << 8) | __NET_USHORT_BYTE_1(x))
   11.89 -#define SET_NET_USHORT(y, x) *((USHORT *)&(y)) = ((__NET_USHORT_BYTE_0(x) << 8) | __NET_USHORT_BYTE_1(x))
   11.90 -*/
   11.91 -
   11.92 -static FORCEINLINE USHORT
   11.93 -GET_NET_USHORT(USHORT data)
   11.94 -{
   11.95 -  return (data << 8) | (data >> 8);
   11.96 -}
   11.97 -
   11.98 -static FORCEINLINE USHORT
   11.99 -GET_NET_PUSHORT(PVOID pdata)
  11.100 -{
  11.101 -  return (*((PUSHORT)pdata) << 8) | (*((PUSHORT)pdata) >> 8);
  11.102 -}
  11.103 -
  11.104 -static FORCEINLINE VOID
  11.105 -SET_NET_USHORT(PVOID ptr, USHORT data)
  11.106 -{
  11.107 -  *((PUSHORT)ptr) = GET_NET_USHORT(data);
  11.108 -}
  11.109 -
  11.110 -static FORCEINLINE ULONG
  11.111 -GET_NET_ULONG(ULONG data)
  11.112 -{
  11.113 -  ULONG tmp;
  11.114 -  
  11.115 -  tmp = ((data & 0x00ff00ff) << 8) | ((data & 0xff00ff00) >> 8);
  11.116 -  return (tmp << 16) | (tmp >> 16);
  11.117 -}
  11.118 -
  11.119 -static FORCEINLINE ULONG
  11.120 -GET_NET_PULONG(PVOID pdata)
  11.121 -{
  11.122 -  ULONG tmp;
  11.123 -  
  11.124 -  tmp = ((*((PULONG)pdata) & 0x00ff00ff) << 8) | ((*((PULONG)pdata) & 0xff00ff00) >> 8);
  11.125 -  return (tmp << 16) | (tmp >> 16);
  11.126 -}
  11.127 -
  11.128 -static FORCEINLINE VOID
  11.129 -SET_NET_ULONG(PVOID ptr, ULONG data)
  11.130 -{
  11.131 -  *((PULONG)ptr) = GET_NET_ULONG(data);
  11.132 -}
  11.133 -/*
  11.134 -#define GET_NET_ULONG(x) ((GET_NET_USHORT(x) << 16) | GET_NET_USHORT(((PUCHAR)&x)[2]))
  11.135 -#define SET_NET_ULONG(y, x) *((ULONG *)&(y)) = ((GET_NET_USHORT(x) << 16) | GET_NET_USHORT(((PUCHAR)&x)[2]))
  11.136 -*/
  11.137 -
  11.138 -#define SUPPORTED_PACKET_FILTERS (\
  11.139 -  NDIS_PACKET_TYPE_DIRECTED | \
  11.140 -  NDIS_PACKET_TYPE_MULTICAST | \
  11.141 -  NDIS_PACKET_TYPE_BROADCAST | \
  11.142 -  NDIS_PACKET_TYPE_PROMISCUOUS | \
  11.143 -  NDIS_PACKET_TYPE_ALL_MULTICAST)
  11.144 -
  11.145 -/* couldn't get regular xen ring macros to work...*/
  11.146 -#define __NET_RING_SIZE(type, _sz) \
  11.147 -    (__RD32( \
  11.148 -    (_sz - sizeof(struct type##_sring) + sizeof(union type##_sring_entry)) \
  11.149 -    / sizeof(union type##_sring_entry)))
  11.150 -
  11.151 -#define NET_TX_RING_SIZE __NET_RING_SIZE(netif_tx, PAGE_SIZE)
  11.152 -#define NET_RX_RING_SIZE __NET_RING_SIZE(netif_rx, PAGE_SIZE)
  11.153 -
  11.154 -#pragma warning(disable: 4127) // conditional expression is constant
  11.155 -
  11.156 -#define MIN_LARGE_SEND_SEGMENTS 4
  11.157 -
  11.158 -/* TODO: crank this up if we support higher mtus? */
  11.159 -#define XN_HDR_SIZE 14
  11.160 -#define XN_MAX_DATA_SIZE 1500
  11.161 -#define XN_MIN_FRAME_SIZE 60
  11.162 -#define XN_MAX_FRAME_SIZE (XN_HDR_SIZE + XN_DATA_SIZE)
  11.163 -/*
  11.164 -#if !defined(OFFLOAD_LARGE_SEND)
  11.165 -  #define XN_MAX_PKT_SIZE (XN_HDR_SIZE + XN_DATA_SIZE)
  11.166 -#else
  11.167 -  #define XN_MAX_PKT_SIZE MAX_LARGE_SEND_OFFLOAD
  11.168 -#endif
  11.169 -*/
  11.170 -
  11.171 -#define XN_MAX_SEND_PKTS 16
  11.172 -
  11.173 -#define XENSOURCE_MAC_HDR 0x00163E
  11.174 -#define XN_VENDOR_DESC "Xensource"
  11.175 -#define MAX_XENBUS_STR_LEN 128
  11.176 -
  11.177 -#define RX_MIN_TARGET 8
  11.178 -#define RX_DFL_MIN_TARGET 256
  11.179 -#define RX_MAX_TARGET min(NET_RX_RING_SIZE, 256)
  11.180 -#define RX_MAX_PB_FREELIST (RX_MAX_TARGET * 4)
  11.181 -
  11.182 -//#define MAX_BUFFERS_PER_PACKET NET_RX_RING_SIZE
  11.183 -
  11.184 -#define MIN_ETH_HEADER_LENGTH 14
  11.185 -#define MAX_ETH_HEADER_LENGTH 14
  11.186 -#define MIN_IP4_HEADER_LENGTH 20
  11.187 -#define MAX_IP4_HEADER_LENGTH (15 * 4)
  11.188 -#define MIN_TCP_HEADER_LENGTH 20
  11.189 -#define MAX_TCP_HEADER_LENGTH (15 * 4)
  11.190 -#define MAX_PKT_HEADER_LENGTH (MAX_ETH_HEADER_LENGTH + MAX_IP4_HEADER_LENGTH + MAX_TCP_HEADER_LENGTH)
  11.191 -
  11.192 -#define MIN_LOOKAHEAD_LENGTH (MAX_IP4_HEADER_LENGTH + MAX_TCP_HEADER_LENGTH)
  11.193 -#define MAX_LOOKAHEAD_LENGTH PAGE_SIZE
  11.194 -
  11.195 -#define LINUX_MAX_SG_ELEMENTS 19
  11.196 -
  11.197 -struct _shared_buffer_t;
  11.198 -
  11.199 -typedef struct _shared_buffer_t shared_buffer_t;
  11.200 -
  11.201 -struct _shared_buffer_t
  11.202 -{
  11.203 -  struct netif_rx_response rsp;
  11.204 -  shared_buffer_t *next;
  11.205 -  grant_ref_t gref;
  11.206 -  //USHORT offset;
  11.207 -  PVOID virtual;
  11.208 -  PMDL mdl;
  11.209 -  //USHORT id;
  11.210 -  volatile LONG ref_count;
  11.211 -};
  11.212 -
  11.213 -typedef struct
  11.214 -{
  11.215 -  PNET_BUFFER nb; /* only set on the last packet */
  11.216 -  PVOID *cb;
  11.217 -  grant_ref_t gref;
  11.218 -} tx_shadow_t;
  11.219 -
  11.220 -typedef struct {
  11.221 -  ULONG parse_result;
  11.222 -  PMDL first_mdl;
  11.223 -  MDL first_mdl_storage;
  11.224 -  PPFN_NUMBER first_mdl_pfns[17]; /* maximum possible packet size */
  11.225 -  PMDL curr_mdl;
  11.226 -  shared_buffer_t *first_pb;
  11.227 -  shared_buffer_t *curr_pb;
  11.228 -  PUCHAR first_mdl_virtual;
  11.229 -  //ULONG mdl_count;
  11.230 -  ULONG first_mdl_offset;
  11.231 -  ULONG first_mdl_length;
  11.232 -  ULONG curr_mdl_offset;
  11.233 -  USHORT mss;
  11.234 -  //NDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
  11.235 -  BOOLEAN csum_blank;
  11.236 -  BOOLEAN data_validated;
  11.237 -  BOOLEAN split_required;
  11.238 -  UCHAR ip_version;
  11.239 -  PUCHAR header;
  11.240 -  ULONG header_length;
  11.241 -  UCHAR ip_proto;
  11.242 -  ULONG total_length;
  11.243 -  USHORT ip4_header_length;
  11.244 -  USHORT ip4_length;
  11.245 -  USHORT tcp_header_length;
  11.246 -  BOOLEAN tcp_has_options;
  11.247 -  USHORT tcp_length;
  11.248 -  USHORT tcp_remaining;
  11.249 -  ULONG tcp_seq;
  11.250 -  BOOLEAN is_multicast;
  11.251 -  BOOLEAN is_broadcast;
  11.252 -  /* anything past here doesn't get cleared automatically by the ClearPacketInfo */
  11.253 -  UCHAR header_data[MAX_LOOKAHEAD_LENGTH + MAX_ETH_HEADER_LENGTH];
  11.254 -} packet_info_t;
  11.255 -
  11.256 -#define PAGE_LIST_SIZE (max(NET_RX_RING_SIZE, NET_TX_RING_SIZE) * 4)
  11.257 -#define MULTICAST_LIST_MAX_SIZE 32
  11.258 -
  11.259 -/* split incoming large packets into MSS sized chunks */
  11.260 -#define RX_LSO_SPLIT_MSS 0
  11.261 -/* split incoming large packets in half, to not invoke the delayed ack timer */
  11.262 -#define RX_LSO_SPLIT_HALF 1
  11.263 -/* don't split incoming large packets. not really useful */
  11.264 -#define RX_LSO_SPLIT_NONE 2
  11.265 -
  11.266 -#define DEVICE_STATE_DISCONNECTED  0 /* -> INITIALISING */
  11.267 -#define DEVICE_STATE_INITIALISING  1 /* -> ACTIVE or INACTIVE */
  11.268 -#define DEVICE_STATE_INACTIVE      2
  11.269 -#define DEVICE_STATE_ACTIVE        3 /* -> DISCONNECTING */
  11.270 -#define DEVICE_STATE_DISCONNECTING 4 /* -> DISCONNECTED */
  11.271 -
  11.272 -struct xennet_info
  11.273 -{
  11.274 -  ULONG device_state;
  11.275 -  
  11.276 -  /* Base device vars */
  11.277 -  PDEVICE_OBJECT pdo;
  11.278 -  PDEVICE_OBJECT fdo;
  11.279 -  PDEVICE_OBJECT lower_do;
  11.280 -  //WDFDEVICE wdf_device;
  11.281 -  WCHAR dev_desc[NAME_SIZE];
  11.282 -
  11.283 -  /* NDIS-related vars */
  11.284 -  NDIS_HANDLE adapter_handle;
  11.285 -  ULONG packet_filter;
  11.286 -  //BOOLEAN connected;
  11.287 -  uint8_t perm_mac_addr[ETH_ALEN];
  11.288 -  uint8_t curr_mac_addr[ETH_ALEN];
  11.289 -  ULONG current_lookahead;
  11.290 -  //NDIS_DEVICE_POWER_STATE new_power_state;
  11.291 -  //NDIS_DEVICE_POWER_STATE power_state;
  11.292 -  //PIO_WORKITEM power_workitem;
  11.293 -
  11.294 -  /* Misc. Xen vars */
  11.295 -  XN_HANDLE handle;
  11.296 -  //XENPCI_VECTORS vectors;
  11.297 -  
  11.298 -  //PXENPCI_DEVICE_STATE device_state;
  11.299 -  evtchn_port_t event_channel;
  11.300 -  //ULONG state;
  11.301 -  //char backend_path[MAX_XENBUS_STR_LEN];
  11.302 -  ULONG backend_state;
  11.303 -  KEVENT backend_event;
  11.304 -  //PVOID config_page;
  11.305 -  UCHAR multicast_list[MULTICAST_LIST_MAX_SIZE][6];
  11.306 -  ULONG multicast_list_size;
  11.307 -  //KDPC suspend_dpc;
  11.308 -  //PIO_WORKITEM resume_work_item;
  11.309 -  //KSPIN_LOCK resume_lock;
  11.310 -  KDPC rxtx_dpc;
  11.311 -
  11.312 -  /* tx related - protected by tx_lock */
  11.313 -  KSPIN_LOCK tx_lock; /* always acquire rx_lock before tx_lock */
  11.314 -  LIST_ENTRY tx_waiting_pkt_list;
  11.315 -  netif_tx_sring_t *tx_sring;
  11.316 -  grant_ref_t tx_sring_gref;
  11.317 -  struct netif_tx_front_ring tx_ring;
  11.318 -  ULONG tx_ring_free;
  11.319 -  tx_shadow_t tx_shadows[NET_TX_RING_SIZE];
  11.320 -#define TX_HEADER_BUFFER_SIZE 512
  11.321 -#define TX_COALESCE_BUFFERS (NET_TX_RING_SIZE)
  11.322 -  ULONG tx_outstanding;
  11.323 -  ULONG tx_id_free;
  11.324 -  USHORT tx_id_list[NET_TX_RING_SIZE];
  11.325 -  NPAGED_LOOKASIDE_LIST tx_lookaside_list;
  11.326 -  KEVENT tx_idle_event;
  11.327 -
  11.328 -  /* rx_related - protected by rx_lock */
  11.329 -  KSPIN_LOCK rx_lock; /* always acquire rx_lock before tx_lock */
  11.330 -  netif_rx_sring_t *rx_sring;
  11.331 -  grant_ref_t rx_sring_gref;
  11.332 -  struct netif_rx_front_ring rx_ring;
  11.333 -  ULONG rx_id_free;
  11.334 -  packet_info_t *rxpi;
  11.335 -  KEVENT packet_returned_event;
  11.336 -  NDIS_HANDLE rx_nbl_pool;
  11.337 -  NDIS_HANDLE rx_nb_pool;
  11.338 -  volatile LONG rx_pb_free;
  11.339 -  struct stack_state *rx_pb_stack;
  11.340 -  volatile LONG rx_hb_free;
  11.341 -  struct stack_state *rx_hb_stack;
  11.342 -  shared_buffer_t *rx_ring_pbs[NET_RX_RING_SIZE];
  11.343 -  /* Receive-ring batched refills. */
  11.344 -  ULONG rx_target;
  11.345 -  ULONG rx_max_target;
  11.346 -  ULONG rx_min_target;
  11.347 -  shared_buffer_t *rx_partial_buf;
  11.348 -  BOOLEAN rx_partial_extra_info_flag ;
  11.349 -  BOOLEAN rx_partial_more_data_flag;
  11.350 -  KEVENT rx_idle_event;
  11.351 -  /* how many packets are in the net stack atm */
  11.352 -  LONG rx_outstanding;
  11.353 -
  11.354 -
  11.355 -  /* config vars from registry */
  11.356 -  /* the frontend_* indicate our willingness to support */
  11.357 -  BOOLEAN frontend_sg_supported;
  11.358 -  BOOLEAN frontend_csum_supported;
  11.359 -  ULONG frontend_gso_value;
  11.360 -  ULONG frontend_mtu_value;
  11.361 -  ULONG frontend_gso_rx_split_type; /* RX_LSO_SPLIT_* */
  11.362 -
  11.363 -  BOOLEAN backend_sg_supported;
  11.364 -  BOOLEAN backend_csum_supported;
  11.365 -  ULONG backend_gso_value;
  11.366 -  
  11.367 -  BOOLEAN current_sg_supported;
  11.368 -  BOOLEAN current_csum_supported;
  11.369 -  ULONG current_gso_value;
  11.370 -  ULONG current_mtu_value;
  11.371 -  ULONG current_gso_rx_split_type;
  11.372 -
  11.373 -  /* config stuff calculated from the above */
  11.374 -  ULONG config_max_pkt_size;
  11.375 -
  11.376 -  /* stats */\
  11.377 -  NDIS_STATISTICS_INFO stats;
  11.378 -  //ULONG64 stat_tx_ok;
  11.379 -  //ULONG64 stat_rx_ok;
  11.380 -  //ULONG64 stat_tx_error;
  11.381 -  //ULONG64 stat_rx_error;
  11.382 -  //ULONG64 stat_rx_no_buffer;
  11.383 -  
  11.384 -} typedef xennet_info_t;
  11.385 -
  11.386 -struct xennet_oids_t {
  11.387 -  ULONG oid;
  11.388 -  char *oid_name;
  11.389 -  ULONG min_length;
  11.390 -  MINIPORT_OID_REQUEST *query_routine;
  11.391 -  MINIPORT_OID_REQUEST *set_routine;
  11.392 -};
  11.393 -
  11.394 -extern struct xennet_oids_t xennet_oids[];
  11.395 -
  11.396 -extern USHORT ndis_os_major_version;
  11.397 -extern USHORT ndis_os_minor_version;
  11.398 -
  11.399 -
  11.400 -MINIPORT_OID_REQUEST XenNet_OidRequest;
  11.401 -MINIPORT_CANCEL_OID_REQUEST XenNet_CancelOidRequest;
  11.402 -
  11.403 -MINIPORT_SEND_NET_BUFFER_LISTS XenNet_SendNetBufferLists;
  11.404 -MINIPORT_CANCEL_SEND XenNet_CancelSend;
  11.405 -
  11.406 -MINIPORT_RETURN_NET_BUFFER_LISTS XenNet_ReturnNetBufferLists;
  11.407 -
  11.408 -BOOLEAN XenNet_RxInit(xennet_info_t *xi);
  11.409 -VOID XenNet_RxShutdown(xennet_info_t *xi);
  11.410 -BOOLEAN XenNet_RxBufferCheck(struct xennet_info *xi);
  11.411 -
  11.412 -BOOLEAN XenNet_TxInit(xennet_info_t *xi);
  11.413 -BOOLEAN XenNet_TxShutdown(xennet_info_t *xi);
  11.414 -VOID XenNet_TxBufferGC(struct xennet_info *xi, BOOLEAN dont_set_event);
  11.415 -
  11.416 -#if 0
  11.417 -NDIS_STATUS
  11.418 -XenNet_D0Entry(struct xennet_info *xi);
  11.419 -NDIS_STATUS
  11.420 -XenNet_D0Exit(struct xennet_info *xi);
  11.421 -IO_WORKITEM_ROUTINE
  11.422 -XenNet_SetPower;
  11.423 -#endif
  11.424 -
  11.425 -/* return values */
  11.426 -#define PARSE_OK 0
  11.427 -#define PARSE_TOO_SMALL 1 /* first buffer is too small */
  11.428 -#define PARSE_UNKNOWN_TYPE 2
  11.429 -
  11.430 -BOOLEAN
  11.431 -XenNet_BuildHeader(packet_info_t *pi, PVOID header, ULONG new_header_size);
  11.432 -VOID
  11.433 -XenNet_ParsePacketHeader(packet_info_t *pi, PUCHAR buffer, ULONG min_header_size);
  11.434 -BOOLEAN
  11.435 -XenNet_FilterAcceptPacket(struct xennet_info *xi,packet_info_t *pi);
  11.436 -
  11.437 -VOID
  11.438 -XenNet_SumIpHeader(
  11.439 -  PUCHAR header,
  11.440 -  USHORT ip4_header_length
  11.441 -);
  11.442 -
  11.443 -static __forceinline VOID
  11.444 -XenNet_ClearPacketInfo(packet_info_t *pi)
  11.445 -{
  11.446 -  RtlZeroMemory(pi, sizeof(packet_info_t) - FIELD_OFFSET(packet_info_t, header_data));
  11.447 -}
  11.448 -
  11.449 -/* Get some data from the current packet, but don't cross a page boundry. */
  11.450 -static __forceinline ULONG
  11.451 -XenNet_QueryData(packet_info_t *pi, ULONG length)
  11.452 -{
  11.453 -  ULONG offset_in_page;
  11.454 -  
  11.455 -  if (length > MmGetMdlByteCount(pi->curr_mdl) - pi->curr_mdl_offset)
  11.456 -    length = MmGetMdlByteCount(pi->curr_mdl) - pi->curr_mdl_offset;
  11.457 -
  11.458 -  offset_in_page = (MmGetMdlByteOffset(pi->curr_mdl) + pi->curr_mdl_offset) & (PAGE_SIZE - 1);
  11.459 -  if (offset_in_page + length > PAGE_SIZE)
  11.460 -    length = PAGE_SIZE - offset_in_page;
  11.461 -  
  11.462 -  return length;
  11.463 -}
  11.464 -
  11.465 -/* Move the pointers forward by the given amount. No error checking is done.  */
  11.466 -static __forceinline VOID
  11.467 -XenNet_EatData(packet_info_t *pi, ULONG length)
  11.468 -{
  11.469 -  pi->curr_mdl_offset += length;
  11.470 -  if (pi->curr_mdl_offset >= MmGetMdlByteCount(pi->curr_mdl))
  11.471 -  {
  11.472 -    pi->curr_mdl_offset -= MmGetMdlByteCount(pi->curr_mdl);
  11.473 -    NdisGetNextMdl(pi->curr_mdl, &pi->curr_mdl);
  11.474 -  }
  11.475 -}
    12.1 --- a/xennet/xennet6_common.c	Sun Feb 10 23:12:03 2013 +1100
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,313 +0,0 @@
    12.4 -/*
    12.5 -PV Net Driver for Windows Xen HVM Domains
    12.6 -Copyright (C) 2007 James Harper
    12.7 -Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
    12.8 -
    12.9 -This program is free software; you can redistribute it and/or
   12.10 -modify it under the terms of the GNU General Public License
   12.11 -as published by the Free Software Foundation; either version 2
   12.12 -of the License, or (at your option) any later version.
   12.13 -
   12.14 -This program is distributed in the hope that it will be useful,
   12.15 -but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.16 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12.17 -GNU General Public License for more details.
   12.18 -
   12.19 -You should have received a copy of the GNU General Public License
   12.20 -along with this program; if not, write to the Free Software
   12.21 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   12.22 -*/
   12.23 -
   12.24 -#include "xennet6.h"
   12.25 -
   12.26 -/* Increase the header to a certain size */
   12.27 -BOOLEAN
   12.28 -XenNet_BuildHeader(packet_info_t *pi, PUCHAR header, ULONG new_header_size)
   12.29 -{
   12.30 -  ULONG bytes_remaining;
   12.31 -
   12.32 -  //FUNCTION_ENTER();
   12.33 -
   12.34 -  if (!header)
   12.35 -    header = pi->header;
   12.36 -
   12.37 -  if (new_header_size > pi->total_length)
   12.38 -  {
   12.39 -    new_header_size = pi->total_length;
   12.40 -  }
   12.41 -
   12.42 -  if (new_header_size <= pi->header_length)
   12.43 -  {
   12.44 -    //FUNCTION_EXIT();
   12.45 -    return TRUE; /* header is already at least the required size */
   12.46 -  }
   12.47 -
   12.48 -  if (header == pi->first_mdl_virtual)
   12.49 -  {
   12.50 -    /* still working in the first buffer */
   12.51 -    if (new_header_size <= pi->first_mdl_length)
   12.52 -    {
   12.53 -      //KdPrint((__DRIVER_NAME "     new_header_size <= pi->first_mdl_length\n"));
   12.54 -      pi->header_length = new_header_size;
   12.55 -      if (pi->header_length == pi->first_mdl_length)
   12.56 -      {
   12.57 -        NdisGetNextMdl(pi->curr_mdl, &pi->curr_mdl);
   12.58 -        pi->curr_mdl_offset = 0;
   12.59 -        if (pi->curr_pb)
   12.60 -          pi->curr_pb = pi->curr_pb->next;
   12.61 -      }
   12.62 -      else
   12.63 -      {
   12.64 -        pi->curr_mdl_offset = (USHORT)new_header_size;
   12.65 -      }
   12.66 -      //FUNCTION_EXIT();
   12.67 -      return TRUE;
   12.68 -    }
   12.69 -    else
   12.70 -    {
   12.71 -      //KdPrint((__DRIVER_NAME "     Switching to header_data\n"));
   12.72 -      memcpy(pi->header_data, header, pi->header_length);
   12.73 -      header = pi->header = pi->header_data;
   12.74 -    }
   12.75 -  }
   12.76 -  
   12.77 -  bytes_remaining = new_header_size - pi->header_length;
   12.78 -  // TODO: if there are only a small number of bytes left in the current buffer then increase to consume that too... it would have to be no more than the size of header+mss though
   12.79 -
   12.80 -  //KdPrint((__DRIVER_NAME "     A bytes_remaining = %d, pi->curr_mdl = %p\n", bytes_remaining, pi->curr_mdl));
   12.81 -  while (bytes_remaining && pi->curr_mdl)
   12.82 -  {
   12.83 -    ULONG copy_size;
   12.84 -    
   12.85 -    ASSERT(pi->curr_mdl);
   12.86 -    //KdPrint((__DRIVER_NAME "     B bytes_remaining = %d, pi->curr_mdl = %p\n", bytes_remaining, pi->curr_mdl));
   12.87 -    if (MmGetMdlByteCount(pi->curr_mdl))
   12.88 -    {
   12.89 -      PUCHAR src_addr;
   12.90 -      src_addr = MmGetSystemAddressForMdlSafe(pi->curr_mdl, NormalPagePriority);
   12.91 -      if (!src_addr)
   12.92 -      {
   12.93 -        //FUNCTION_EXIT();
   12.94 -        return FALSE;
   12.95 -      }
   12.96 -      copy_size = min(bytes_remaining, MmGetMdlByteCount(pi->curr_mdl) - pi->curr_mdl_offset);
   12.97 -      //KdPrint((__DRIVER_NAME "     B copy_size = %d\n", copy_size));
   12.98 -      memcpy(header + pi->header_length,
   12.99 -        src_addr + pi->curr_mdl_offset, copy_size);
  12.100 -      pi->curr_mdl_offset = (USHORT)(pi->curr_mdl_offset + copy_size);
  12.101 -      pi->header_length += copy_size;
  12.102 -      bytes_remaining -= copy_size;
  12.103 -    }
  12.104 -    if (pi->curr_mdl_offset == MmGetMdlByteCount(pi->curr_mdl))
  12.105 -    {
  12.106 -      NdisGetNextMdl(pi->curr_mdl, &pi->curr_mdl);
  12.107 -      if (pi->curr_pb)
  12.108 -        pi->curr_pb = pi->curr_pb->next;
  12.109 -      pi->curr_mdl_offset = 0;
  12.110 -    }
  12.111 -  }
  12.112 -  //KdPrint((__DRIVER_NAME "     C bytes_remaining = %d, pi->curr_mdl = %p\n", bytes_remaining, pi->curr_mdl));
  12.113 -  if (bytes_remaining)
  12.114 -  {
  12.115 -    //KdPrint((__DRIVER_NAME "     bytes_remaining\n"));
  12.116 -    //FUNCTION_EXIT();
  12.117 -    return FALSE;
  12.118 -  }
  12.119 -  //FUNCTION_EXIT();
  12.120 -  return TRUE;
  12.121 -}
  12.122 -
  12.123 -VOID
  12.124 -XenNet_ParsePacketHeader(packet_info_t *pi, PUCHAR alt_buffer, ULONG min_header_size)
  12.125 -{
  12.126 -  //FUNCTION_ENTER();
  12.127 -
  12.128 -  ASSERT(pi->first_mdl);
  12.129 -  
  12.130 -  NdisQueryMdl(pi->first_mdl, (PVOID)&pi->first_mdl_virtual, &pi->first_mdl_length, NormalPagePriority);
  12.131 -  pi->curr_mdl = pi->first_mdl;
  12.132 -  if (alt_buffer)
  12.133 -    pi->header = alt_buffer;
  12.134 -  else
  12.135 -    pi->header = pi->first_mdl_virtual;
  12.136 -
  12.137 -  pi->header_length = 0;
  12.138 -  pi->curr_mdl_offset = pi->first_mdl_offset;
  12.139 -
  12.140 -  XenNet_BuildHeader(pi, NULL, min_header_size);
  12.141 -  
  12.142 -  if (!XenNet_BuildHeader(pi, NULL, (ULONG)XN_HDR_SIZE))
  12.143 -  {
  12.144 -    //KdPrint((__DRIVER_NAME "     packet too small (Ethernet Header)\n"));
  12.145 -    pi->parse_result = PARSE_TOO_SMALL;
  12.146 -    return;
  12.147 -  }
  12.148 -
  12.149 -  if (pi->header[0] == 0xFF && pi->header[1] == 0xFF
  12.150 -      && pi->header[2] == 0xFF && pi->header[3] == 0xFF
  12.151 -      && pi->header[4] == 0xFF && pi->header[5] == 0xFF)
  12.152 -  {
  12.153 -    pi->is_broadcast = TRUE;
  12.154 -  }
  12.155 -  else if (pi->header[0] & 0x01)
  12.156 -  {
  12.157 -    pi->is_multicast = TRUE;
  12.158 -  }
  12.159 -
  12.160 -  switch (GET_NET_PUSHORT(&pi->header[12])) // L2 protocol field
  12.161 -  {
  12.162 -  case 0x0800: /* IPv4 */
  12.163 -    //KdPrint((__DRIVER_NAME "     IP\n"));
  12.164 -    if (pi->header_length < (ULONG)(XN_HDR_SIZE + 20))
  12.165 -    {
  12.166 -      if (!XenNet_BuildHeader(pi, NULL, (ULONG)(XN_HDR_SIZE + 20)))
  12.167 -      {
  12.168 -        KdPrint((__DRIVER_NAME "     packet too small (IP Header)\n"));
  12.169 -        pi->parse_result = PARSE_TOO_SMALL;
  12.170 -        return;
  12.171 -      }
  12.172 -    }
  12.173 -    pi->ip_version = (pi->header[XN_HDR_SIZE + 0] & 0xF0) >> 4;
  12.174 -    if (pi->ip_version != 4)
  12.175 -    {
  12.176 -      //KdPrint((__DRIVER_NAME "     ip_version = %d\n", pi->ip_version));
  12.177 -      pi->parse_result = PARSE_UNKNOWN_TYPE;
  12.178 -      return;
  12.179 -    }
  12.180 -    pi->ip4_header_length = (pi->header[XN_HDR_SIZE + 0] & 0x0F) << 2;
  12.181 -    if (pi->header_length < (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20))
  12.182 -    {
  12.183 -      if (!XenNet_BuildHeader(pi, NULL, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20)))
  12.184 -      {
  12.185 -        //KdPrint((__DRIVER_NAME "     packet too small (IP Header + IP Options + TCP Header)\n"));
  12.186 -        pi->parse_result = PARSE_TOO_SMALL;
  12.187 -        return;
  12.188 -      }
  12.189 -    }
  12.190 -    break;
  12.191 -  case 0x86DD:  /* IPv6 */
  12.192 -    //KdPrint((__DRIVER_NAME "     IPv6\n"));
  12.193 -    //KdPrint((__DRIVER_NAME "     (not currently used)\n"));
  12.194 -    pi->parse_result = PARSE_UNKNOWN_TYPE;
  12.195 -    return;
  12.196 -  default:
  12.197 -    //KdPrint((__DRIVER_NAME "     Not IP (%04x)\n", GET_NET_PUSHORT(&pi->header[12])));
  12.198 -    pi->parse_result = PARSE_UNKNOWN_TYPE;
  12.199 -    return;
  12.200 -  }
  12.201 -  pi->ip_proto = pi->header[XN_HDR_SIZE + 9];
  12.202 -  switch (pi->ip_proto)
  12.203 -  {
  12.204 -  case 6:  // TCP
  12.205 -  case 17: // UDP
  12.206 -    break;
  12.207 -  default:
  12.208 -    //KdPrint((__DRIVER_NAME "     Not TCP/UDP (%d)\n", pi->ip_proto));
  12.209 -    pi->parse_result = PARSE_UNKNOWN_TYPE;
  12.210 -    return;
  12.211 -  }
  12.212 -  pi->ip4_length = GET_NET_PUSHORT(&pi->header[XN_HDR_SIZE + 2]);
  12.213 -  pi->tcp_header_length = (pi->header[XN_HDR_SIZE + pi->ip4_header_length + 12] & 0xf0) >> 2;
  12.214 -
  12.215 -  if (pi->header_length < (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + pi->tcp_header_length))
  12.216 -  {
  12.217 -    /* we don't actually need the tcp options to analyse the header */
  12.218 -    if (!XenNet_BuildHeader(pi, NULL, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + MIN_TCP_HEADER_LENGTH)))
  12.219 -    {
  12.220 -      //KdPrint((__DRIVER_NAME "     packet too small (IP Header + IP Options + TCP Header (not including TCP Options))\n"));
  12.221 -      pi->parse_result = PARSE_TOO_SMALL;
  12.222 -      return;
  12.223 -    }
  12.224 -  }
  12.225 -
  12.226 -  if ((ULONG)XN_HDR_SIZE + pi->ip4_length > pi->total_length)
  12.227 -  {
  12.228 -    //KdPrint((__DRIVER_NAME "     XN_HDR_SIZE + ip4_length (%d) > total_length (%d)\n", XN_HDR_SIZE + pi->ip4_length, pi->total_length));
  12.229 -    pi->parse_result = PARSE_UNKNOWN_TYPE;
  12.230 -    return;
  12.231 -  }
  12.232 -
  12.233 -  pi->tcp_length = pi->ip4_length - pi->ip4_header_length - pi->tcp_header_length;
  12.234 -  pi->tcp_remaining = pi->tcp_length;
  12.235 -  pi->tcp_seq = GET_NET_PULONG(&pi->header[XN_HDR_SIZE + pi->ip4_header_length + 4]);
  12.236 -  pi->tcp_has_options = (BOOLEAN)(pi->tcp_header_length > 20);
  12.237 -  if (pi->mss > 0 && pi->tcp_length > pi->mss)
  12.238 -    pi->split_required = TRUE;
  12.239 -
  12.240 -  //KdPrint((__DRIVER_NAME "     ip4_length = %d\n", pi->ip4_length));
  12.241 -  //KdPrint((__DRIVER_NAME "     tcp_length = %d\n", pi->tcp_length));
  12.242 -  //FUNCTION_EXIT();
  12.243 -  
  12.244 -  pi->parse_result = PARSE_OK;
  12.245 -}
  12.246 -
  12.247 -VOID
  12.248 -XenNet_SumIpHeader(
  12.249 -  PUCHAR header,
  12.250 -  USHORT ip4_header_length
  12.251 -)
  12.252 -{
  12.253 -  ULONG csum = 0;
  12.254 -  USHORT i;
  12.255 -
  12.256 -  ASSERT(ip4_header_length > 12);
  12.257 -  ASSERT(!(ip4_header_length & 1));
  12.258 -
  12.259 -  header[XN_HDR_SIZE + 10] = 0;
  12.260 -  header[XN_HDR_SIZE + 11] = 0;
  12.261 -  for (i = 0; i < ip4_header_length; i += 2)
  12.262 -  {
  12.263 -    csum += GET_NET_PUSHORT(&header[XN_HDR_SIZE + i]);
  12.264 -  }
  12.265 -  while (csum & 0xFFFF0000)
  12.266 -    csum = (csum & 0xFFFF) + (csum >> 16);
  12.267 -  csum = ~csum;
  12.268 -  SET_NET_USHORT(&header[XN_HDR_SIZE + 10], (USHORT)csum);
  12.269 -}
  12.270 -
  12.271 -BOOLEAN
  12.272 -XenNet_FilterAcceptPacket(struct xennet_info *xi,packet_info_t *pi)
  12.273 -{
  12.274 -  ULONG i;
  12.275 -  BOOLEAN is_my_multicast = FALSE;
  12.276 -  BOOLEAN is_directed = FALSE;
  12.277 -
  12.278 -  if (memcmp(xi->curr_mac_addr, pi->header, ETH_ALEN) == 0)
  12.279 -  {
  12.280 -    is_directed = TRUE;
  12.281 -  }
  12.282 -  else if (pi->is_multicast)
  12.283 -  {
  12.284 -    for (i = 0; i < xi->multicast_list_size; i++)
  12.285 -    {
  12.286 -      if (memcmp(xi->multicast_list[i], pi->header, 6) == 0)
  12.287 -        break;
  12.288 -    }
  12.289 -    if (i < xi->multicast_list_size)
  12.290 -    {
  12.291 -      is_my_multicast = TRUE;
  12.292 -    }
  12.293 -  }
  12.294 -  if (is_directed && (xi->packet_filter & NDIS_PACKET_TYPE_DIRECTED))
  12.295 -  {
  12.296 -    return TRUE;
  12.297 -  }
  12.298 -  if (is_my_multicast && (xi->packet_filter & NDIS_PACKET_TYPE_MULTICAST))
  12.299 -  {
  12.300 -    return TRUE;
  12.301 -  }
  12.302 -  if (pi->is_multicast && (xi->packet_filter & NDIS_PACKET_TYPE_ALL_MULTICAST))
  12.303 -  {
  12.304 -    return TRUE;
  12.305 -  }
  12.306 -  if (pi->is_broadcast && (xi->packet_filter & NDIS_PACKET_TYPE_BROADCAST))
  12.307 -  {
  12.308 -    return TRUE;
  12.309 -  }
  12.310 -  if (xi->packet_filter & NDIS_PACKET_TYPE_PROMISCUOUS)
  12.311 -  {
  12.312 -    return TRUE;
  12.313 -  }
  12.314 -  //return TRUE;
  12.315 -  return FALSE;
  12.316 -}
    13.1 --- a/xennet/xennet6_oid.c	Sun Feb 10 23:12:03 2013 +1100
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,485 +0,0 @@
    13.4 -/*
    13.5 -PV Net Driver for Windows Xen HVM Domains
    13.6 -Copyright (C) 2007 James Harper
    13.7 -Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
    13.8 -
    13.9 -This program is free software; you can redistribute it and/or
   13.10 -modify it under the terms of the GNU General Public License
   13.11 -as published by the Free Software Foundation; either version 2
   13.12 -of the License, or (at your option) any later version.
   13.13 -
   13.14 -This program is distributed in the hope that it will be useful,
   13.15 -but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.16 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13.17 -GNU General Public License for more details.
   13.18 -
   13.19 -You should have received a copy of the GNU General Public License
   13.20 -along with this program; if not, write to the Free Software
   13.21 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   13.22 -*/
   13.23 -
   13.24 -#include "xennet6.h"
   13.25 -
   13.26 -#define DEF_OID_QUERY(oid, min_length) {oid, #oid, min_length, XenNet_Query##oid, NULL}
   13.27 -#define DEF_OID_QUERYSET(oid, min_length) {oid, #oid, min_length, XenNet_Query##oid, XenNet_Set##oid}
   13.28 -#define DEF_OID_SET(oid, min_length) {oid, #oid, min_length, NULL, XenNet_Set##oid}
   13.29 -#define DEF_OID_NONE(oid) {oid, #oid, 0, NULL, NULL} /* define this for a silent but unsupported oid */
   13.30 -
   13.31 -#define DEF_OID_QUERY_STAT(oid) DEF_OID_QUERY(##oid, 0) /* has to be 0 so the 4/8 size works */
   13.32 -#define DEF_OID_QUERY_ULONG(oid) DEF_OID_QUERY(##oid, sizeof(ULONG))
   13.33 -#define DEF_OID_QUERYSET_ULONG(oid) DEF_OID_QUERYSET(##oid, sizeof(ULONG))
   13.34 -#define DEF_OID_SET_ULONG(oid) DEF_OID_SET(##oid, sizeof(ULONG))
   13.35 -
   13.36 -#define DEF_OID_QUERY_ROUTINE(oid, value, length) \
   13.37 -NDIS_STATUS \
   13.38 -XenNet_Query##oid(NDIS_HANDLE context, PNDIS_OID_REQUEST request) \
   13.39 -{ \
   13.40 -  struct xennet_info *xi = context; \
   13.41 -  UNREFERENCED_PARAMETER(xi); \
   13.42 -  if (request->DATA.QUERY_INFORMATION.InformationBufferLength < length) \
   13.43 -  { \
   13.44 -    request->DATA.QUERY_INFORMATION.BytesNeeded = length; \
   13.45 -    return NDIS_STATUS_BUFFER_TOO_SHORT; \
   13.46 -  } \
   13.47 -  request->DATA.QUERY_INFORMATION.BytesWritten = length; \
   13.48 -  NdisMoveMemory(request->DATA.QUERY_INFORMATION.InformationBuffer, value, length); \
   13.49 -  return STATUS_SUCCESS; \
   13.50 -}
   13.51 -
   13.52 -#define DEF_OID_QUERY_ULONG_ROUTINE(oid, value) \
   13.53 -NDIS_STATUS \
   13.54 -XenNet_Query##oid(NDIS_HANDLE context, PNDIS_OID_REQUEST request) \
   13.55 -{ \
   13.56 -  struct xennet_info *xi = context; \
   13.57 -  UNREFERENCED_PARAMETER(xi); \
   13.58 -  request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(ULONG); \
   13.59 -  *(ULONG *)request->DATA.QUERY_INFORMATION.InformationBuffer = value; \
   13.60 -  return STATUS_SUCCESS; \
   13.61 -}
   13.62 -
   13.63 -#define DEF_OID_QUERY_STAT_ROUTINE(oid, value) \
   13.64 -NDIS_STATUS \
   13.65 -XenNet_Query##oid(NDIS_HANDLE context, PNDIS_OID_REQUEST request) \
   13.66 -{ \
   13.67 -  struct xennet_info *xi = context; \
   13.68 -  UNREFERENCED_PARAMETER(xi); \
   13.69 -  if (request->DATA.QUERY_INFORMATION.InformationBufferLength >= 8) \
   13.70 -  { \
   13.71 -    request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(ULONG64); \
   13.72 -    *(ULONG64 *)request->DATA.QUERY_INFORMATION.InformationBuffer = (value); \
   13.73 -  } \
   13.74 -  else if (request->DATA.QUERY_INFORMATION.InformationBufferLength >= 4) \
   13.75 -  { \
   13.76 -    request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(ULONG); \
   13.77 -    request->DATA.QUERY_INFORMATION.BytesNeeded = sizeof(ULONG64); \
   13.78 -    *(ULONG *)request->DATA.QUERY_INFORMATION.InformationBuffer = (ULONG)(value); \
   13.79 -  } \
   13.80 -  else \
   13.81 -  { \
   13.82 -    request->DATA.QUERY_INFORMATION.BytesNeeded = sizeof(ULONG64); \
   13.83 -    return NDIS_STATUS_BUFFER_TOO_SHORT; \
   13.84 -  } \
   13.85 -  return STATUS_SUCCESS; \
   13.86 -}
   13.87 -
   13.88 -DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_MAXIMUM_TOTAL_SIZE, xi->current_mtu_value + XN_HDR_SIZE)
   13.89 -DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_CURRENT_PACKET_FILTER, xi->packet_filter)
   13.90 -DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_CURRENT_LOOKAHEAD, xi->current_lookahead)
   13.91 -DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_TRANSMIT_BUFFER_SPACE, PAGE_SIZE * NET_TX_RING_SIZE * 4)
   13.92 -DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_RECEIVE_BUFFER_SPACE, PAGE_SIZE * NET_RX_RING_SIZE * 2)
   13.93 -DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_TRANSMIT_BLOCK_SIZE, PAGE_SIZE)
   13.94 -DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_RECEIVE_BLOCK_SIZE, PAGE_SIZE)
   13.95 -DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_MAXIMUM_SEND_PACKETS, 0)
   13.96 -DEF_OID_QUERY_ULONG_ROUTINE(OID_802_3_MAXIMUM_LIST_SIZE, MULTICAST_LIST_MAX_SIZE)
   13.97 -DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_HARDWARE_STATUS, (xi->device_state != DEVICE_STATE_INACTIVE)?NdisHardwareStatusReady:NdisHardwareStatusInitializing)
   13.98 -DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_VENDOR_ID, 0xFFFFFF) // Not guaranteed to be XENSOURCE_MAC_HDR;
   13.99 -DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_VENDOR_DRIVER_VERSION, VENDOR_DRIVER_VERSION)
  13.100 -DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_MEDIA_SUPPORTED, NdisMedium802_3)
  13.101 -DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_MEDIA_IN_USE, NdisMedium802_3)
  13.102 -DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_MAXIMUM_LOOKAHEAD, MAX_LOOKAHEAD_LENGTH)
  13.103 -
  13.104 -DEF_OID_QUERY_STAT_ROUTINE(OID_GEN_XMIT_OK, xi->stats.ifHCOutUcastPkts + xi->stats.ifHCOutMulticastPkts + xi->stats.ifHCOutBroadcastPkts)
  13.105 -DEF_OID_QUERY_STAT_ROUTINE(OID_GEN_XMIT_ERROR, xi->stats.ifOutErrors)
  13.106 -DEF_OID_QUERY_STAT_ROUTINE(OID_GEN_RCV_OK, xi->stats.ifHCInUcastPkts + xi->stats.ifHCInMulticastPkts + xi->stats.ifHCInBroadcastPkts)
  13.107 -DEF_OID_QUERY_STAT_ROUTINE(OID_GEN_RCV_ERROR, xi->stats.ifInErrors)
  13.108 -DEF_OID_QUERY_STAT_ROUTINE(OID_GEN_RCV_NO_BUFFER, xi->stats.ifInDiscards)
  13.109 -DEF_OID_QUERY_STAT_ROUTINE(OID_802_3_RCV_ERROR_ALIGNMENT, 0)
  13.110 -DEF_OID_QUERY_STAT_ROUTINE(OID_802_3_XMIT_ONE_COLLISION, 0)
  13.111 -DEF_OID_QUERY_STAT_ROUTINE(OID_802_3_XMIT_MORE_COLLISIONS, 0)
  13.112 -
  13.113 -DEF_OID_QUERY_ROUTINE(OID_GEN_VENDOR_DESCRIPTION, XN_VENDOR_DESC, sizeof(XN_VENDOR_DESC))
  13.114 -
  13.115 -DEF_OID_QUERY_ROUTINE(OID_802_3_PERMANENT_ADDRESS, xi->perm_mac_addr, ETH_ALEN)
  13.116 -DEF_OID_QUERY_ROUTINE(OID_802_3_CURRENT_ADDRESS, xi->curr_mac_addr, ETH_ALEN)
  13.117 -
  13.118 -DEF_OID_QUERY_ROUTINE(OID_802_3_MULTICAST_LIST, xi->multicast_list, xi->multicast_list_size * 6)
  13.119 -
  13.120 -NDIS_STATUS
  13.121 -XenNet_SetOID_802_3_MULTICAST_LIST(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
  13.122 -{
  13.123 -  struct xennet_info *xi = context;
  13.124 -  UCHAR *multicast_list;
  13.125 -  int i;
  13.126 -
  13.127 -  if (request->DATA.SET_INFORMATION.InformationBufferLength > MULTICAST_LIST_MAX_SIZE * 6)
  13.128 -  {
  13.129 -    return NDIS_STATUS_MULTICAST_FULL;
  13.130 -  }
  13.131 -  
  13.132 -  if (request->DATA.SET_INFORMATION.InformationBufferLength % 6 != 0)
  13.133 -  {
  13.134 -    return NDIS_STATUS_MULTICAST_FULL;
  13.135 -  }
  13.136 -  multicast_list = request->DATA.SET_INFORMATION.InformationBuffer;
  13.137 -  for (i = 0; i < (int)request->DATA.SET_INFORMATION.InformationBufferLength / 6; i++)
  13.138 -  {
  13.139 -    if (!(multicast_list[i * 6 + 0] & 0x01))
  13.140 -    {
  13.141 -      FUNCTION_MSG("Address %d (%02x:%02x:%02x:%02x:%02x:%02x) is not a multicast address\n", i,
  13.142 -        (ULONG)multicast_list[i * 6 + 0], (ULONG)multicast_list[i * 6 + 1], 
  13.143 -        (ULONG)multicast_list[i * 6 + 2], (ULONG)multicast_list[i * 6 + 3], 
  13.144 -        (ULONG)multicast_list[i * 6 + 4], (ULONG)multicast_list[i * 6 + 5]);
  13.145 -      /* the docs say that we should return NDIS_STATUS_MULTICAST_FULL if we get an invalid multicast address but I'm not sure if that's the case... */
  13.146 -    }
  13.147 -  }
  13.148 -  memcpy(xi->multicast_list, multicast_list, request->DATA.SET_INFORMATION.InformationBufferLength);
  13.149 -  xi->multicast_list_size = request->DATA.SET_INFORMATION.InformationBufferLength / 6;
  13.150 -  return NDIS_STATUS_SUCCESS;
  13.151 -}
  13.152 -
  13.153 -NDIS_STATUS
  13.154 -XenNet_SetOID_GEN_CURRENT_PACKET_FILTER(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
  13.155 -{
  13.156 -  struct xennet_info *xi = context;
  13.157 -  PULONG data = request->DATA.SET_INFORMATION.InformationBuffer;
  13.158 -  
  13.159 -  request->DATA.SET_INFORMATION.BytesNeeded = sizeof(ULONG64);
  13.160 -  if (*data & NDIS_PACKET_TYPE_DIRECTED)
  13.161 -    FUNCTION_MSG("NDIS_PACKET_TYPE_DIRECTED\n");
  13.162 -  if (*data & NDIS_PACKET_TYPE_MULTICAST)
  13.163 -    FUNCTION_MSG("NDIS_PACKET_TYPE_MULTICAST\n");
  13.164 -  if (*data & NDIS_PACKET_TYPE_ALL_MULTICAST)
  13.165 -    FUNCTION_MSG("NDIS_PACKET_TYPE_ALL_MULTICAST\n");
  13.166 -  if (*data & NDIS_PACKET_TYPE_BROADCAST)
  13.167 -    FUNCTION_MSG("NDIS_PACKET_TYPE_BROADCAST\n");
  13.168 -  if (*data & NDIS_PACKET_TYPE_PROMISCUOUS)
  13.169 -    FUNCTION_MSG("NDIS_PACKET_TYPE_PROMISCUOUS\n");
  13.170 -  if (*data & NDIS_PACKET_TYPE_ALL_FUNCTIONAL)
  13.171 -    FUNCTION_MSG("NDIS_PACKET_TYPE_ALL_FUNCTIONAL (not supported)\n");
  13.172 -  if (*data & NDIS_PACKET_TYPE_ALL_LOCAL)
  13.173 -    FUNCTION_MSG("NDIS_PACKET_TYPE_ALL_LOCAL (not supported)\n");
  13.174 -  if (*data & NDIS_PACKET_TYPE_FUNCTIONAL)
  13.175 -    FUNCTION_MSG("NDIS_PACKET_TYPE_FUNCTIONAL (not supported)\n");
  13.176 -  if (*data & NDIS_PACKET_TYPE_GROUP)
  13.177 -    FUNCTION_MSG("NDIS_PACKET_TYPE_GROUP (not supported)\n");
  13.178 -  if (*data & ~SUPPORTED_PACKET_FILTERS)
  13.179 -  {
  13.180 -    FUNCTION_MSG("returning NDIS_STATUS_NOT_SUPPORTED\n");
  13.181 -    return NDIS_STATUS_NOT_SUPPORTED;
  13.182 -  }
  13.183 -  xi->packet_filter = *(ULONG *)data;
  13.184 -  request->DATA.SET_INFORMATION.BytesRead = sizeof(ULONG);
  13.185 -  return NDIS_STATUS_SUCCESS;
  13.186 -}
  13.187 -
  13.188 -NDIS_STATUS
  13.189 -XenNet_SetOID_GEN_CURRENT_LOOKAHEAD(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
  13.190 -{
  13.191 -  struct xennet_info *xi = context;
  13.192 -  PULONG data = request->DATA.QUERY_INFORMATION.InformationBuffer;
  13.193 -  xi->current_lookahead = *(ULONG *)data;
  13.194 -  FUNCTION_MSG("Set OID_GEN_CURRENT_LOOKAHEAD %d (%p)\n", xi->current_lookahead, xi);
  13.195 -  return NDIS_STATUS_SUCCESS;
  13.196 -}
  13.197 -
  13.198 -NDIS_STATUS
  13.199 -XenNet_SetOID_GEN_LINK_PARAMETERS(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
  13.200 -{
  13.201 -  UNREFERENCED_PARAMETER(context);
  13.202 -  UNREFERENCED_PARAMETER(request);
  13.203 -  return STATUS_NOT_SUPPORTED;
  13.204 -}
  13.205 -
  13.206 -NDIS_STATUS
  13.207 -XenNet_QueryOID_GEN_INTERRUPT_MODERATION(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
  13.208 -{
  13.209 -  PNDIS_INTERRUPT_MODERATION_PARAMETERS nimp;
  13.210 -  UNREFERENCED_PARAMETER(context);
  13.211 -  nimp = (PNDIS_INTERRUPT_MODERATION_PARAMETERS)request->DATA.QUERY_INFORMATION.InformationBuffer;
  13.212 -  nimp->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
  13.213 -  nimp->Header.Revision = NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
  13.214 -  nimp->Header.Size = NDIS_SIZEOF_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
  13.215 -  nimp->Flags = 0;
  13.216 -  nimp->InterruptModeration = NdisInterruptModerationNotSupported;
  13.217 -  request->DATA.SET_INFORMATION.BytesRead = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS);
  13.218 -  return STATUS_SUCCESS;
  13.219 -}
  13.220 -
  13.221 -NDIS_STATUS
  13.222 -XenNet_SetOID_GEN_INTERRUPT_MODERATION(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
  13.223 -{
  13.224 -  UNREFERENCED_PARAMETER(context);
  13.225 -  UNREFERENCED_PARAMETER(request);
  13.226 -  return STATUS_NOT_SUPPORTED;
  13.227 -}
  13.228 -
  13.229 -NDIS_STATUS
  13.230 -XenNet_QueryOID_GEN_STATISTICS(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
  13.231 -{
  13.232 -  struct xennet_info *xi = context;
  13.233 -
  13.234 -  NdisMoveMemory(request->DATA.QUERY_INFORMATION.InformationBuffer, &xi->stats, sizeof(NDIS_STATISTICS_INFO));
  13.235 -  request->DATA.SET_INFORMATION.BytesRead = sizeof(NDIS_STATISTICS_INFO);
  13.236 -  return STATUS_SUCCESS;
  13.237 -}
  13.238 -
  13.239 -NDIS_STATUS
  13.240 -XenNet_SetOID_PNP_SET_POWER(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
  13.241 -{
  13.242 -  UNREFERENCED_PARAMETER(context);
  13.243 -  UNREFERENCED_PARAMETER(request);
  13.244 -  return STATUS_NOT_SUPPORTED;
  13.245 -}
  13.246 -
  13.247 -NDIS_STATUS
  13.248 -XenNet_SetOID_GEN_NETWORK_LAYER_ADDRESSES(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
  13.249 -{
  13.250 -  PNETWORK_ADDRESS_LIST nal = request->DATA.QUERY_INFORMATION.InformationBuffer;
  13.251 -  PNETWORK_ADDRESS na;
  13.252 -  PNETWORK_ADDRESS_IP ip;
  13.253 -  int i;
  13.254 -  
  13.255 -  UNREFERENCED_PARAMETER(context);
  13.256 -  FUNCTION_MSG("AddressType = %d\n", nal->AddressType);
  13.257 -  FUNCTION_MSG("AddressCount = %d\n", nal->AddressCount);
  13.258 -  if (nal->AddressCount == 0)
  13.259 -  {
  13.260 -    // remove addresses of AddressType type
  13.261 -  }
  13.262 -  else
  13.263 -  {
  13.264 -    na = nal->Address;
  13.265 -    for (i = 0; i < nal->AddressCount; i++)
  13.266 -    {
  13.267 -      if ((ULONG_PTR)na - (ULONG_PTR)nal + FIELD_OFFSET(NETWORK_ADDRESS, Address) + na->AddressLength > request->DATA.QUERY_INFORMATION.InformationBufferLength)
  13.268 -      {
  13.269 -        FUNCTION_MSG("Out of bounds\n");
  13.270 -        return NDIS_STATUS_INVALID_DATA;
  13.271 -      }
  13.272 -      switch(na->AddressType)
  13.273 -      {
  13.274 -      case NDIS_PROTOCOL_ID_TCP_IP:
  13.275 -        FUNCTION_MSG("Address[%d].Type = NDIS_PROTOCOL_ID_TCP_IP\n", i);
  13.276 -        FUNCTION_MSG("Address[%d].Length = %d\n", i, na->AddressLength);
  13.277 -        if (na->AddressLength != NETWORK_ADDRESS_LENGTH_IP)
  13.278 -        {
  13.279 -          FUNCTION_MSG("Length is invalid\n");
  13.280 -          break;
  13.281 -        }
  13.282 -        ip = (PNETWORK_ADDRESS_IP)na->Address;
  13.283 -        FUNCTION_MSG("Address[%d].in_addr = %d.%d.%d.%d\n", i, ip->in_addr & 0xff, (ip->in_addr >> 8) & 0xff, (ip->in_addr >> 16) & 0xff, (ip->in_addr >> 24) & 0xff);
  13.284 -        break;
  13.285 -      default:
  13.286 -        FUNCTION_MSG("Address[%d].Type = %d\n", i, na->AddressType);
  13.287 -        FUNCTION_MSG("Address[%d].Length = %d\n", i, na->AddressLength);
  13.288 -        break;
  13.289 -      }
  13.290 -      na = (PNETWORK_ADDRESS)((PUCHAR)na + FIELD_OFFSET(NETWORK_ADDRESS, Address) + na->AddressLength);
  13.291 -    }
  13.292 -  }
  13.293 -  
  13.294 -  return NDIS_STATUS_SUCCESS;
  13.295 -}
  13.296 -
  13.297 -NDIS_STATUS
  13.298 -XenNet_SetOID_GEN_MACHINE_NAME(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
  13.299 -{
  13.300 -  UNICODE_STRING name;
  13.301 -  UNREFERENCED_PARAMETER(context);
  13.302 -  
  13.303 -  name.Length = (USHORT)request->DATA.QUERY_INFORMATION.InformationBufferLength;
  13.304 -  name.MaximumLength = (USHORT)request->DATA.QUERY_INFORMATION.InformationBufferLength;
  13.305 -  name.Buffer = request->DATA.QUERY_INFORMATION.InformationBuffer;
  13.306 -  FUNCTION_MSG("name = %wZ\n", &name);
  13.307 -  return NDIS_STATUS_SUCCESS;
  13.308 -}
  13.309 -
  13.310 -NDIS_STATUS
  13.311 -XenNet_SetOID_OFFLOAD_ENCAPSULATION(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
  13.312 -{
  13.313 -  struct xennet_info *xi = context;
  13.314 -  /* mostly assume that NDIS vets the settings for us */
  13.315 -  PNDIS_OFFLOAD_ENCAPSULATION noe = (PNDIS_OFFLOAD_ENCAPSULATION)request->DATA.SET_INFORMATION.InformationBuffer;
  13.316 -  if (noe->IPv4.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3)
  13.317 -  {
  13.318 -    FUNCTION_MSG("Unknown Encapsulation Type %d\n", noe->IPv4.EncapsulationType);
  13.319 -    return NDIS_STATUS_NOT_SUPPORTED;
  13.320 -  }
  13.321 -    
  13.322 -  switch(noe->IPv4.Enabled)
  13.323 -  {
  13.324 -  case NDIS_OFFLOAD_SET_ON:
  13.325 -    FUNCTION_MSG(" IPv4.Enabled = NDIS_OFFLOAD_SET_ON\n");
  13.326 -    xi->current_csum_supported = xi->backend_csum_supported && xi->frontend_csum_supported;
  13.327 -    xi->current_gso_value = min(xi->backend_csum_supported, xi->frontend_csum_supported);
  13.328 -    break;
  13.329 -  case NDIS_OFFLOAD_SET_OFF:
  13.330 -    FUNCTION_MSG(" IPv4.Enabled = NDIS_OFFLOAD_SET_OFF\n");
  13.331 -    xi->current_csum_supported = FALSE;
  13.332 -    xi->current_gso_value = 0;
  13.333 -    break;
  13.334 -  case NDIS_OFFLOAD_SET_NO_CHANGE:
  13.335 -    FUNCTION_MSG(" IPv4.Enabled = NDIS_OFFLOAD_NO_CHANGE\n");
  13.336 -    break;
  13.337 -  }
  13.338 -  FUNCTION_MSG(" IPv4.HeaderSize = %d\n", noe->IPv4.HeaderSize);
  13.339 -  FUNCTION_MSG(" IPv6.EncapsulationType = %d\n", noe->IPv6.EncapsulationType);
  13.340 -  switch(noe->IPv6.Enabled)
  13.341 -  {
  13.342 -  case NDIS_OFFLOAD_SET_ON:
  13.343 -    FUNCTION_MSG(" IPv6.Enabled = NDIS_OFFLOAD_SET_ON (this is an error)\n");
  13.344 -    break;
  13.345 -  case NDIS_OFFLOAD_SET_OFF:
  13.346 -    FUNCTION_MSG(" IPv6.Enabled = NDIS_OFFLOAD_SET_OFF\n");
  13.347 -    break;
  13.348 -  case NDIS_OFFLOAD_SET_NO_CHANGE:
  13.349 -    FUNCTION_MSG(" IPv6.Enabled = NDIS_OFFLOAD_NO_CHANGE\n");
  13.350 -    break;
  13.351 -  }
  13.352 -  FUNCTION_MSG(" IPv6.HeaderSize = %d\n", noe->IPv6.HeaderSize);
  13.353 -  return NDIS_STATUS_SUCCESS;
  13.354 -}
  13.355 -
  13.356 -struct xennet_oids_t xennet_oids[] = {
  13.357 -  DEF_OID_QUERY_ULONG(OID_GEN_HARDWARE_STATUS),
  13.358 -
  13.359 -  DEF_OID_QUERY_ULONG(OID_GEN_TRANSMIT_BUFFER_SPACE),
  13.360 -  DEF_OID_QUERY_ULONG(OID_GEN_RECEIVE_BUFFER_SPACE),
  13.361 -  DEF_OID_QUERY_ULONG(OID_GEN_TRANSMIT_BLOCK_SIZE),
  13.362 -  DEF_OID_QUERY_ULONG(OID_GEN_RECEIVE_BLOCK_SIZE),
  13.363 -
  13.364 -  DEF_OID_QUERY_ULONG(OID_GEN_VENDOR_ID),
  13.365 -  DEF_OID_QUERY(OID_GEN_VENDOR_DESCRIPTION, sizeof(XN_VENDOR_DESC)),
  13.366 -  DEF_OID_QUERY_ULONG(OID_GEN_VENDOR_DRIVER_VERSION),
  13.367 -
  13.368 -  DEF_OID_QUERYSET_ULONG(OID_GEN_CURRENT_PACKET_FILTER),
  13.369 -  DEF_OID_QUERYSET_ULONG(OID_GEN_CURRENT_LOOKAHEAD),
  13.370 -  DEF_OID_QUERY_ULONG(OID_GEN_MAXIMUM_TOTAL_SIZE),
  13.371 -  DEF_OID_SET(OID_GEN_LINK_PARAMETERS, sizeof(NDIS_LINK_PARAMETERS)),
  13.372 -  DEF_OID_QUERYSET(OID_GEN_INTERRUPT_MODERATION, sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS)),
  13.373 -  
  13.374 -  DEF_OID_QUERY_ULONG(OID_GEN_MAXIMUM_SEND_PACKETS),
  13.375 -  DEF_OID_QUERY_ULONG(OID_GEN_MEDIA_SUPPORTED),
  13.376 -  DEF_OID_QUERY_ULONG(OID_GEN_MEDIA_IN_USE),
  13.377 -  DEF_OID_QUERY_ULONG(OID_GEN_MAXIMUM_LOOKAHEAD),
  13.378 -
  13.379 -  /* general optional */
  13.380 -  DEF_OID_SET(OID_GEN_NETWORK_LAYER_ADDRESSES, FIELD_OFFSET(NETWORK_ADDRESS_LIST, Address)),
  13.381 -  DEF_OID_SET(OID_GEN_MACHINE_NAME, 0),
  13.382 -  DEF_OID_SET(OID_OFFLOAD_ENCAPSULATION, sizeof(NDIS_OFFLOAD_ENCAPSULATION)),
  13.383 -
  13.384 -  /* power */
  13.385 -  DEF_OID_SET_ULONG(OID_PNP_SET_POWER),
  13.386 -  
  13.387 -  /* stats */
  13.388 -  DEF_OID_QUERY_STAT(OID_GEN_XMIT_OK),
  13.389 -  DEF_OID_QUERY_STAT(OID_GEN_RCV_OK),
  13.390 -  DEF_OID_QUERY_STAT(OID_GEN_XMIT_ERROR),
  13.391 -  DEF_OID_QUERY_STAT(OID_GEN_RCV_ERROR),
  13.392 -  DEF_OID_QUERY_STAT(OID_GEN_RCV_NO_BUFFER),
  13.393 -  DEF_OID_QUERY_STAT(OID_802_3_RCV_ERROR_ALIGNMENT),
  13.394 -  DEF_OID_QUERY_STAT(OID_802_3_XMIT_ONE_COLLISION),
  13.395 -  DEF_OID_QUERY_STAT(OID_802_3_XMIT_MORE_COLLISIONS),
  13.396 -  DEF_OID_NONE(OID_IP4_OFFLOAD_STATS),
  13.397 -  DEF_OID_NONE(OID_IP6_OFFLOAD_STATS),
  13.398 -  DEF_OID_QUERY(OID_GEN_STATISTICS, sizeof(NDIS_STATISTICS_INFO)),
  13.399 -
  13.400 -  /* media-specific */
  13.401 -  DEF_OID_QUERY(OID_802_3_PERMANENT_ADDRESS, 6),
  13.402 -  DEF_OID_QUERY(OID_802_3_CURRENT_ADDRESS, 6),
  13.403 -  DEF_OID_QUERYSET(OID_802_3_MULTICAST_LIST, 0),
  13.404 -  DEF_OID_QUERY_ULONG(OID_802_3_MAXIMUM_LIST_SIZE),
  13.405 -  
  13.406 -  {0, "", 0, NULL, NULL}
  13.407 -};
  13.408 -
  13.409 -//static NDIS_OID supported_oids[ARRAY_SIZE(xennet_oids)];
  13.410 -
  13.411 -NDIS_STATUS
  13.412 -XenNet_OidRequest(NDIS_HANDLE adapter_context, PNDIS_OID_REQUEST oid_request)
  13.413 -{
  13.414 -  NTSTATUS status;
  13.415 -  int i;
  13.416 -  NDIS_OID oid;
  13.417 -  MINIPORT_OID_REQUEST *routine;
  13.418 -  
  13.419 -  //FUNCTION_ENTER();
  13.420 -  switch(oid_request->RequestType)
  13.421 -  {
  13.422 -  case NdisRequestQueryInformation:
  13.423 -    //FUNCTION_MSG("RequestType = NdisRequestQueryInformation\n");
  13.424 -    oid = oid_request->DATA.QUERY_INFORMATION.Oid;
  13.425 -    break;
  13.426 -  case NdisRequestSetInformation:
  13.427 -    //FUNCTION_MSG("RequestType = NdisRequestSetInformation\n");
  13.428 -    oid = oid_request->DATA.SET_INFORMATION.Oid;
  13.429 -    break;
  13.430 -  case NdisRequestQueryStatistics:
  13.431 -    //FUNCTION_MSG("RequestType = NdisRequestQueryStatistics\n");
  13.432 -    oid = oid_request->DATA.QUERY_INFORMATION.Oid;
  13.433 -    break;
  13.434 -  default:
  13.435 -    //FUNCTION_MSG("RequestType = NdisRequestQuery%d\n", oid_request->RequestType);
  13.436 -    return NDIS_STATUS_NOT_SUPPORTED;
  13.437 -  }
  13.438 -  for (i = 0; xennet_oids[i].oid && xennet_oids[i].oid != oid; i++);
  13.439 -
  13.440 -  if (!xennet_oids[i].oid)
  13.441 -  {
  13.442 -    FUNCTION_MSG("Unsupported OID %08x\n", oid);
  13.443 -    return NDIS_STATUS_NOT_SUPPORTED;
  13.444 -  }
  13.445 -  //FUNCTION_MSG("Oid = %s\n", xennet_oids[i].oid_name);
  13.446 -  routine = NULL;
  13.447 -  switch(oid_request->RequestType)
  13.448 -  {
  13.449 -  case NdisRequestQueryInformation:
  13.450 -  case NdisRequestQueryStatistics:
  13.451 -    if (oid_request->DATA.QUERY_INFORMATION.InformationBufferLength < xennet_oids[i].min_length)
  13.452 -    {
  13.453 -      FUNCTION_MSG("InformationBufferLength %d < min_length %d\n", oid_request->DATA.QUERY_INFORMATION.InformationBufferLength < xennet_oids[i].min_length);
  13.454 -      oid_request->DATA.QUERY_INFORMATION.BytesNeeded = xennet_oids[i].min_length;
  13.455 -      return NDIS_STATUS_BUFFER_TOO_SHORT;
  13.456 -    }
  13.457 -    routine =  xennet_oids[i].query_routine;
  13.458 -    break;
  13.459 -  case NdisRequestSetInformation:
  13.460 -    if (oid_request->DATA.SET_INFORMATION.InformationBufferLength < xennet_oids[i].min_length)
  13.461 -    {
  13.462 -      FUNCTION_MSG("InformationBufferLength %d < min_length %d\n", oid_request->DATA.SET_INFORMATION.InformationBufferLength < xennet_oids[i].min_length);
  13.463 -      oid_request->DATA.SET_INFORMATION.BytesNeeded = xennet_oids[i].min_length;
  13.464 -      return NDIS_STATUS_BUFFER_TOO_SHORT;
  13.465 -    }
  13.466 -    routine =  xennet_oids[i].set_routine;
  13.467 -    break;
  13.468 -  }
  13.469 -  if (!routine)
  13.470 -  {
  13.471 -    //FUNCTION_MSG("Operation not supported\n");
  13.472 -    return NDIS_STATUS_NOT_SUPPORTED;
  13.473 -  }
  13.474 -  status = routine(adapter_context, oid_request);
  13.475 -  //FUNCTION_MSG("status = %08x\n", status);
  13.476 -  
  13.477 -  //FUNCTION_EXIT();
  13.478 -  return status;
  13.479 -}
  13.480 -
  13.481 -VOID
  13.482 -XenNet_CancelOidRequest(NDIS_HANDLE adapter_context, PVOID request_id)
  13.483 -{
  13.484 -  UNREFERENCED_PARAMETER(adapter_context);
  13.485 -  UNREFERENCED_PARAMETER(request_id);
  13.486 -  FUNCTION_ENTER();
  13.487 -  FUNCTION_EXIT();
  13.488 -}
    14.1 --- a/xennet/xennet6_rx.c	Sun Feb 10 23:12:03 2013 +1100
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,943 +0,0 @@
    14.4 -/*
    14.5 -PV Net Driver for Windows Xen HVM Domains
    14.6 -Copyright (C) 2007 James Harper
    14.7 -Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
    14.8 -
    14.9 -This program is free software; you can redistribute it and/or
   14.10 -modify it under the terms of the GNU General Public License
   14.11 -as published by the Free Software Foundation; either version 2
   14.12 -of the License, or (at your option) any later version.
   14.13 -
   14.14 -This program is distributed in the hope that it will be useful,
   14.15 -but WITHOUT ANY WARRANTY; without even the implied warranty of
   14.16 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14.17 -GNU General Public License for more details.
   14.18 -
   14.19 -You should have received a copy of the GNU General Public License
   14.20 -along with this program; if not, write to the Free Software
   14.21 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   14.22 -*/
   14.23 -
   14.24 -#include "xennet6.h"
   14.25 -
   14.26 -static __inline shared_buffer_t *
   14.27 -get_pb_from_freelist(struct xennet_info *xi)
   14.28 -{
   14.29 -  shared_buffer_t *pb;
   14.30 -  PVOID ptr_ref;
   14.31 -
   14.32 -  if (stack_pop(xi->rx_pb_stack, &ptr_ref))
   14.33 -  {
   14.34 -    pb = ptr_ref;
   14.35 -    pb->ref_count = 1;
   14.36 -    InterlockedDecrement(&xi->rx_pb_free);
   14.37 -    return pb;
   14.38 -  }
   14.39 -
   14.40 -  /* don't allocate a new one if we are shutting down */
   14.41 -  if (xi->device_state != DEVICE_STATE_INITIALISING && xi->device_state != DEVICE_STATE_ACTIVE)
   14.42 -    return NULL;
   14.43 -    
   14.44 -  pb = NdisAllocateMemoryWithTagPriority(xi->adapter_handle, sizeof(shared_buffer_t), XENNET_POOL_TAG, LowPoolPriority);
   14.45 -  if (!pb)
   14.46 -    return NULL;
   14.47 -  pb->virtual = NdisAllocateMemoryWithTagPriority(xi->adapter_handle, PAGE_SIZE, XENNET_POOL_TAG, LowPoolPriority);
   14.48 -  if (!pb->virtual)
   14.49 -  {
   14.50 -    NdisFreeMemory(pb, sizeof(shared_buffer_t), 0);
   14.51 -    return NULL;
   14.52 -  }
   14.53 -  pb->mdl = IoAllocateMdl(pb->virtual, PAGE_SIZE, FALSE, FALSE, NULL);
   14.54 -  if (!pb->mdl)
   14.55 -  {
   14.56 -    NdisFreeMemory(pb->virtual, PAGE_SIZE, 0);
   14.57 -    NdisFreeMemory(pb, sizeof(shared_buffer_t), 0);
   14.58 -    return NULL;
   14.59 -  }
   14.60 -  pb->gref = (grant_ref_t)XnGrantAccess(xi->handle,
   14.61 -            (ULONG)(MmGetPhysicalAddress(pb->virtual).QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, (ULONG)'XNRX');
   14.62 -  if (pb->gref == INVALID_GRANT_REF)
   14.63 -  {
   14.64 -    IoFreeMdl(pb->mdl);
   14.65 -    NdisFreeMemory(pb->virtual, PAGE_SIZE, 0);
   14.66 -    NdisFreeMemory(pb, sizeof(shared_buffer_t), 0);
   14.67 -    return NULL;
   14.68 -  }
   14.69 -  MmBuildMdlForNonPagedPool(pb->mdl);
   14.70 -  pb->ref_count = 1;
   14.71 -  return pb;
   14.72 -}
   14.73 -
   14.74 -static __inline VOID
   14.75 -ref_pb(struct xennet_info *xi, shared_buffer_t *pb)
   14.76 -{
   14.77 -  UNREFERENCED_PARAMETER(xi);
   14.78 -  InterlockedIncrement(&pb->ref_count);
   14.79 -}
   14.80 -
   14.81 -static __inline VOID
   14.82 -put_pb_on_freelist(struct xennet_info *xi, shared_buffer_t *pb)
   14.83 -{
   14.84 -  if (InterlockedDecrement(&pb->ref_count) == 0)
   14.85 -  {
   14.86 -    //NdisAdjustBufferLength(pb->buffer, PAGE_SIZE);
   14.87 -    //NDIS_BUFFER_LINKAGE(pb->buffer) = NULL;
   14.88 -    if (xi->rx_pb_free > RX_MAX_PB_FREELIST)
   14.89 -    {
   14.90 -      XnEndAccess(xi->handle, pb->gref, FALSE, (ULONG)'XNRX');
   14.91 -      IoFreeMdl(pb->mdl);
   14.92 -      NdisFreeMemory(pb->virtual, PAGE_SIZE, 0);
   14.93 -      NdisFreeMemory(pb, sizeof(shared_buffer_t), 0);
   14.94 -      return;
   14.95 -    }
   14.96 -    pb->mdl->ByteCount = PAGE_SIZE;
   14.97 -    pb->mdl->Next = NULL;
   14.98 -    pb->next = NULL;
   14.99 -    stack_push(xi->rx_pb_stack, pb);
  14.100 -    InterlockedIncrement(&xi->rx_pb_free);
  14.101 -  }
  14.102 -}
  14.103 -
  14.104 -static __inline shared_buffer_t *
  14.105 -get_hb_from_freelist(struct xennet_info *xi)
  14.106 -{
  14.107 -  shared_buffer_t *hb;
  14.108 -  PVOID ptr_ref;
  14.109 -
  14.110 -  if (stack_pop(xi->rx_hb_stack, &ptr_ref))
  14.111 -  {
  14.112 -    hb = ptr_ref;
  14.113 -    InterlockedDecrement(&xi->rx_hb_free);
  14.114 -    return hb;
  14.115 -  }
  14.116 -
  14.117 -  /* don't allocate a new one if we are shutting down */
  14.118 -  if (xi->device_state != DEVICE_STATE_INITIALISING && xi->device_state != DEVICE_STATE_ACTIVE)
  14.119 -    return NULL;
  14.120 -    
  14.121 -  hb = NdisAllocateMemoryWithTagPriority(xi->adapter_handle, sizeof(shared_buffer_t) + MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH, XENNET_POOL_TAG, LowPoolPriority);
  14.122 -  if (!hb)
  14.123 -    return NULL;
  14.124 -  NdisZeroMemory(hb, sizeof(shared_buffer_t));
  14.125 -  hb->mdl = IoAllocateMdl(hb + 1, MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH, FALSE, FALSE, NULL);
  14.126 -  if (!hb->mdl) {
  14.127 -    NdisFreeMemory(hb, sizeof(shared_buffer_t) + MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH, 0);
  14.128 -    return NULL;
  14.129 -  }
  14.130 -  MmBuildMdlForNonPagedPool(hb->mdl);
  14.131 -  return hb;
  14.132 -}
  14.133 -
  14.134 -static __inline VOID
  14.135 -put_hb_on_freelist(struct xennet_info *xi, shared_buffer_t *hb)
  14.136 -{
  14.137 -  NT_ASSERT(xi);
  14.138 -  hb->mdl->ByteCount = sizeof(shared_buffer_t) + MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH;
  14.139 -  hb->mdl->Next = NULL;
  14.140 -  hb->next = NULL;
  14.141 -  stack_push(xi->rx_hb_stack, hb);
  14.142 -  InterlockedIncrement(&xi->rx_hb_free);
  14.143 -}
  14.144 -
  14.145 -// Called at DISPATCH_LEVEL with rx lock held
  14.146 -static NDIS_STATUS
  14.147 -XenNet_FillRing(struct xennet_info *xi)
  14.148 -{
  14.149 -  unsigned short id;
  14.150 -  shared_buffer_t *page_buf;
  14.151 -  ULONG i, notify;
  14.152 -  ULONG batch_target;
  14.153 -  RING_IDX req_prod = xi->rx_ring.req_prod_pvt;
  14.154 -  netif_rx_request_t *req;
  14.155 -
  14.156 -  //FUNCTION_ENTER();
  14.157 -
  14.158 -  batch_target = xi->rx_target - (req_prod - xi->rx_ring.rsp_cons);
  14.159 -
  14.160 -  if (batch_target < (xi->rx_target >> 2)) {
  14.161 -    //FUNCTION_EXIT();
  14.162 -    return NDIS_STATUS_SUCCESS; /* only refill if we are less than 3/4 full already */
  14.163 -  }
  14.164 -
  14.165 -  for (i = 0; i < batch_target; i++) {
  14.166 -    page_buf = get_pb_from_freelist(xi);
  14.167 -    if (!page_buf) {
  14.168 -      KdPrint((__DRIVER_NAME "     Added %d out of %d buffers to rx ring (no free pages)\n", i, batch_target));
  14.169 -      break;
  14.170 -    }
  14.171 -    xi->rx_id_free--;
  14.172 -
  14.173 -    /* Give to netback */
  14.174 -    id = (USHORT)((req_prod + i) & (NET_RX_RING_SIZE - 1));
  14.175 -    NT_ASSERT(xi->rx_ring_pbs[id] == NULL);
  14.176 -    xi->rx_ring_pbs[id] = page_buf;
  14.177 -    req = RING_GET_REQUEST(&xi->rx_ring, req_prod + i);
  14.178 -    req->id = id;
  14.179 -    req->gref = page_buf->gref;
  14.180 -    NT_ASSERT(req->gref != INVALID_GRANT_REF);
  14.181 -  }
  14.182 -  KeMemoryBarrier();
  14.183 -  xi->rx_ring.req_prod_pvt = req_prod + i;
  14.184 -  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xi->rx_ring, notify);
  14.185 -  if (notify) {
  14.186 -    XnNotify(xi->handle, xi->event_channel);
  14.187 -  }
  14.188 -
  14.189 -  //FUNCTION_EXIT();
  14.190 -
  14.191 -  return NDIS_STATUS_SUCCESS;
  14.192 -}
  14.193 -
  14.194 -typedef struct {
  14.195 -  PNET_BUFFER_LIST first_nbl;
  14.196 -  PNET_BUFFER_LIST last_nbl;
  14.197 -  ULONG packet_count;
  14.198 -  ULONG nbl_count;
  14.199 -} rx_context_t;
  14.200 -
  14.201 -static BOOLEAN
  14.202 -XenNet_MakePacket(struct xennet_info *xi, rx_context_t *rc, packet_info_t *pi)
  14.203 -{
  14.204 -  PNET_BUFFER_LIST nbl;
  14.205 -  PNET_BUFFER nb;
  14.206 -  PMDL mdl_head, mdl_tail, curr_mdl;
  14.207 -  PUCHAR header_va;
  14.208 -  ULONG out_remaining;
  14.209 -  ULONG header_extra;
  14.210 -  shared_buffer_t *header_buf;
  14.211 -  NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csum_info;
  14.212 -
  14.213 -  //FUNCTION_ENTER();
  14.214 -  
  14.215 -  nbl = NdisAllocateNetBufferList(xi->rx_nbl_pool, 0, 0);
  14.216 -  if (!nbl)
  14.217 -  {
  14.218 -    /* buffers will be freed in MakePackets */
  14.219 -    KdPrint((__DRIVER_NAME "     No free nbl's\n"));
  14.220 -    //FUNCTION_EXIT();
  14.221 -    return FALSE;
  14.222 -  }
  14.223 -
  14.224 -  nb = NdisAllocateNetBuffer(xi->rx_nb_pool, NULL, 0, 0);
  14.225 -  if (!nb)
  14.226 -  {
  14.227 -    KdPrint((__DRIVER_NAME "     No free nb's\n"));
  14.228 -    NdisFreeNetBufferList(nbl);
  14.229 -    //FUNCTION_EXIT();
  14.230 -    return FALSE;
  14.231 -  }
  14.232 -
  14.233 -  if (!pi->first_mdl->Next && !pi->split_required) {
  14.234 -    /* a single buffer <= MTU */
  14.235 -    header_buf = NULL;
  14.236 -    XenNet_BuildHeader(pi, pi->first_mdl_virtual, pi->first_mdl_length);
  14.237 -    NET_BUFFER_FIRST_MDL(nb) = pi->first_mdl;
  14.238 -    NET_BUFFER_CURRENT_MDL(nb) = pi->first_mdl;
  14.239 -    NET_BUFFER_CURRENT_MDL_OFFSET(nb) = 0;
  14.240 -    NET_BUFFER_DATA_OFFSET(nb) = 0;
  14.241 -    NET_BUFFER_DATA_LENGTH(nb) = pi->total_length;
  14.242 -    NB_FIRST_PB(nb) = pi->first_pb;
  14.243 -    ref_pb(xi, pi->first_pb);
  14.244 -  } else {
  14.245 -    NT_ASSERT(ndis_os_minor_version >= 1);
  14.246 -    header_buf = get_hb_from_freelist(xi);
  14.247 -    if (!header_buf)
  14.248 -    {
  14.249 -      KdPrint((__DRIVER_NAME "     No free header buffers\n"));
  14.250 -      NdisFreeNetBufferList(nbl);
  14.251 -      NdisFreeNetBuffer(nb);
  14.252 -      //FUNCTION_EXIT();
  14.253 -      return FALSE;
  14.254 -    }
  14.255 -    header_va = (PUCHAR)(header_buf + 1);
  14.256 -    NdisMoveMemory(header_va, pi->header, pi->header_length);
  14.257 -    //KdPrint((__DRIVER_NAME "     header_length = %d, current_lookahead = %d\n", pi->header_length, xi->current_lookahead));
  14.258 -    //KdPrint((__DRIVER_NAME "     ip4_header_length = %d\n", pi->ip4_header_length));
  14.259 -    //KdPrint((__DRIVER_NAME "     tcp_header_length = %d\n", pi->tcp_header_length));
  14.260 -    /* make sure only the header is in the first buffer (or the entire packet, but that is done in the above case) */
  14.261 -    XenNet_BuildHeader(pi, header_va, MAX_ETH_HEADER_LENGTH + pi->ip4_header_length + pi->tcp_header_length);
  14.262 -    header_extra = pi->header_length - (MAX_ETH_HEADER_LENGTH + pi->ip4_header_length + pi->tcp_header_length);
  14.263 -    NT_ASSERT(pi->header_length <= MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH);
  14.264 -    header_buf->mdl->ByteCount = pi->header_length;
  14.265 -    mdl_head = mdl_tail = curr_mdl = header_buf->mdl;
  14.266 -    NB_FIRST_PB(nb) = header_buf;
  14.267 -    header_buf->next = pi->curr_pb;
  14.268 -    NET_BUFFER_FIRST_MDL(nb) = mdl_head;
  14.269 -    NET_BUFFER_CURRENT_MDL(nb) = mdl_head;
  14.270 -    NET_BUFFER_CURRENT_MDL_OFFSET(nb) = 0;
  14.271 -    NET_BUFFER_DATA_OFFSET(nb) = 0;
  14.272 -    NET_BUFFER_DATA_LENGTH(nb) = pi->header_length;
  14.273 -
  14.274 -    if (pi->split_required)
  14.275 -    {
  14.276 -      ULONG tcp_length;
  14.277 -      USHORT new_ip4_length;
  14.278 -      tcp_length = (USHORT)min(pi->mss, pi->tcp_remaining);
  14.279 -      new_ip4_length = (USHORT)(pi->ip4_header_length + pi->tcp_header_length + tcp_length);
  14.280 -      //KdPrint((__DRIVER_NAME "     new_ip4_length = %d\n", new_ip4_length));
  14.281 -      //KdPrint((__DRIVER_NAME "     this tcp_length = %d\n", tcp_length));
  14.282 -      SET_NET_USHORT(&header_va[XN_HDR_SIZE + 2], new_ip4_length);
  14.283 -      SET_NET_ULONG(&header_va[XN_HDR_SIZE + pi->ip4_header_length + 4], pi->tcp_seq);
  14.284 -      pi->tcp_seq += tcp_length;
  14.285 -      pi->tcp_remaining = (USHORT)(pi->tcp_remaining - tcp_length);
  14.286 -      /* part of the packet is already present in the header buffer for lookahead */
  14.287 -      out_remaining = tcp_length - header_extra;
  14.288 -      NT_ASSERT((LONG)out_remaining >= 0);
  14.289 -    }
  14.290 -    else
  14.291 -    {
  14.292 -      out_remaining = pi->total_length - pi->header_length;
  14.293 -      NT_ASSERT((LONG)out_remaining >= 0);
  14.294 -    }
  14.295 -    //KdPrint((__DRIVER_NAME "     before loop - out_remaining = %d\n", out_remaining));
  14.296 -
  14.297 -    while (out_remaining != 0)
  14.298 -    {
  14.299 -      //ULONG in_buffer_offset;
  14.300 -      ULONG in_buffer_length;
  14.301 -      ULONG out_length;
  14.302 -      
  14.303 -      //KdPrint((__DRIVER_NAME "     in loop - out_remaining = %d, curr_buffer = %p, curr_pb = %p\n", out_remaining, pi->curr_mdl, pi->curr_pb));
  14.304 -      if (!pi->curr_mdl || !pi->curr_pb)
  14.305 -      {
  14.306 -        KdPrint((__DRIVER_NAME "     out of buffers for packet\n"));
  14.307 -        //KdPrint((__DRIVER_NAME "     out_remaining = %d, curr_buffer = %p, curr_pb = %p\n", out_remaining, pi->curr_mdl, pi->curr_pb));
  14.308 -        // TODO: free some stuff or we'll leak
  14.309 -        /* unchain buffers then free packet */
  14.310 -        //FUNCTION_EXIT();
  14.311 -        return FALSE;
  14.312 -      }
  14.313 -
  14.314 -      in_buffer_length = MmGetMdlByteCount(pi->curr_mdl);
  14.315 -      out_length = min(out_remaining, in_buffer_length - pi->curr_mdl_offset);
  14.316 -      curr_mdl = IoAllocateMdl((PUCHAR)MmGetMdlVirtualAddress(pi->curr_mdl) + pi->curr_mdl_offset, out_length, FALSE, FALSE, NULL);
  14.317 -      NT_ASSERT(curr_mdl);
  14.318 -      IoBuildPartialMdl(pi->curr_mdl, curr_mdl, (PUCHAR)MmGetMdlVirtualAddress(pi->curr_mdl) + pi->curr_mdl_offset, out_length);
  14.319 -      mdl_tail->Next = curr_mdl;
  14.320 -      mdl_tail = curr_mdl;
  14.321 -      curr_mdl->Next = NULL; /* I think this might be redundant */
  14.322 -      NET_BUFFER_DATA_LENGTH(nb) += out_length;
  14.323 -      ref_pb(xi, pi->curr_pb);
  14.324 -      pi->curr_mdl_offset = (USHORT)(pi->curr_mdl_offset + out_length);
  14.325 -      if (pi->curr_mdl_offset == in_buffer_length)
  14.326 -      {
  14.327 -        pi->curr_mdl = pi->curr_mdl->Next;
  14.328 -        pi->curr_pb = pi->curr_pb->next;
  14.329 -        pi->curr_mdl_offset = 0;
  14.330 -      }
  14.331 -      out_remaining -= out_length;
  14.332 -    }
  14.333 -    if (pi->split_required)
  14.334 -    {
  14.335 -      // TODO: only if Ip checksum is disabled...
  14.336 -      //XenNet_SumIpHeader(header_va, pi->ip4_header_length);
  14.337 -    }
  14.338 -    if (header_extra > 0)
  14.339 -      pi->header_length -= header_extra;
  14.340 -    //ASSERT(*(shared_buffer_t **)&packet->MiniportReservedEx[0]);
  14.341 -  }
  14.342 -  
  14.343 -  rc->packet_count++;
  14.344 -  NET_BUFFER_LIST_FIRST_NB(nbl) = nb;
  14.345 -  //NET_BUFFER_NEXT_NB(nb) = NULL; /*is this already done for me? */
  14.346 -
  14.347 -  if (pi->parse_result == PARSE_OK)
  14.348 -  {
  14.349 -    BOOLEAN checksum_offload = FALSE;
  14.350 -    csum_info.Value = 0;
  14.351 -    if (pi->csum_blank || pi->data_validated || pi->mss)
  14.352 -    {
  14.353 -      if (pi->ip_proto == 6) // && xi->setting_csum.V4Receive.TcpChecksum)
  14.354 -      {
  14.355 -//          if (!pi->tcp_has_options || xi->setting_csum.V4Receive.TcpOptionsSupported)
  14.356 -//          {
  14.357 -          csum_info.Receive.IpChecksumSucceeded = TRUE;
  14.358 -          csum_info.Receive.TcpChecksumSucceeded = TRUE;
  14.359 -          checksum_offload = TRUE;
  14.360 -//          }
  14.361 -      }
  14.362 -      else if (pi->ip_proto == 17) // &&xi->setting_csum.V4Receive.UdpChecksum)
  14.363 -      {
  14.364 -        csum_info.Receive.IpChecksumSucceeded = TRUE;
  14.365 -        csum_info.Receive.UdpChecksumSucceeded = TRUE;
  14.366 -        checksum_offload = TRUE;
  14.367 -      }
  14.368 -    }
  14.369 -    NET_BUFFER_LIST_INFO(nbl, TcpIpChecksumNetBufferListInfo) = csum_info.Value;
  14.370 -  }
  14.371 -  
  14.372 -  if (!rc->first_nbl)
  14.373 -  {
  14.374 -    rc->first_nbl = nbl;
  14.375 -  }
  14.376 -  else
  14.377 -  {
  14.378 -    NET_BUFFER_LIST_NEXT_NBL(rc->last_nbl) = nbl;
  14.379 -  }
  14.380 -  rc->last_nbl = nbl;
  14.381 -  NET_BUFFER_LIST_NEXT_NBL(nbl) = NULL;
  14.382 -  rc->nbl_count++;
  14.383 -  InterlockedIncrement(&xi->rx_outstanding);
  14.384 -  if (pi->is_multicast)
  14.385 -  {
  14.386 -    /* multicast */
  14.387 -    xi->stats.ifHCInMulticastPkts++;
  14.388 -    xi->stats.ifHCInMulticastOctets += NET_BUFFER_DATA_LENGTH(nb);
  14.389 -  }
  14.390 -  else if (pi->is_broadcast)
  14.391 -  {
  14.392 -    /* broadcast */
  14.393 -    xi->stats.ifHCInBroadcastPkts++;
  14.394 -    xi->stats.ifHCInBroadcastOctets += NET_BUFFER_DATA_LENGTH(nb);
  14.395 -  }
  14.396 -  else
  14.397 -  {
  14.398 -    /* unicast */
  14.399 -    xi->stats.ifHCInUcastPkts++;
  14.400 -    xi->stats.ifHCInUcastOctets += NET_BUFFER_DATA_LENGTH(nb);
  14.401 -  }
  14.402 -  //FUNCTION_EXIT();
  14.403 -  return TRUE;
  14.404 -}
  14.405 -
  14.406 -static VOID
  14.407 -XenNet_MakePackets(struct xennet_info *xi, rx_context_t *rc, packet_info_t *pi)
  14.408 -{
  14.409 -  UCHAR psh;
  14.410 -  //PNDIS_BUFFER buffer;
  14.411 -  shared_buffer_t *page_buf;
  14.412 -
  14.413 -  //FUNCTION_ENTER();
  14.414 -
  14.415 -  XenNet_ParsePacketHeader(pi, NULL, 0);
  14.416 -  //pi->split_required = FALSE;
  14.417 -
  14.418 -  if (!XenNet_FilterAcceptPacket(xi, pi))
  14.419 -  {
  14.420 -    goto done;
  14.421 -  }
  14.422 -
  14.423 -  if (pi->split_required)
  14.424 -  {
  14.425 -    switch (xi->current_gso_rx_split_type)
  14.426 -    {
  14.427 -    case RX_LSO_SPLIT_HALF:
  14.428 -      pi->mss = max((pi->tcp_length + 1) / 2, pi->mss);
  14.429 -      break;
  14.430 -    case RX_LSO_SPLIT_NONE:
  14.431 -      pi->mss = 65535;
  14.432 -      break;
  14.433 -    }
  14.434 -  }
  14.435 -
  14.436 -  switch (pi->ip_proto)
  14.437 -  {
  14.438 -  case 6:  // TCP
  14.439 -    if (pi->split_required)
  14.440 -      break;
  14.441 -    /* fall through */
  14.442 -  case 17:  // UDP
  14.443 -    if (!XenNet_MakePacket(xi, rc, pi))
  14.444 -    {
  14.445 -      KdPrint((__DRIVER_NAME "     Ran out of packets\n"));
  14.446 -      xi->stats.ifInDiscards++;
  14.447 -      goto done;
  14.448 -    }
  14.449 -    goto done;
  14.450 -  default:
  14.451 -    if (!XenNet_MakePacket(xi, rc, pi))
  14.452 -    {
  14.453 -      KdPrint((__DRIVER_NAME "     Ran out of packets\n"));
  14.454 -      xi->stats.ifInDiscards++;
  14.455 -      goto done;
  14.456 -    }
  14.457 -    goto done;
  14.458 -  }
  14.459 -
  14.460 -  /* this is the split_required code */
  14.461 -  pi->tcp_remaining = pi->tcp_length;
  14.462 -
  14.463 -  /* we can make certain assumptions here as the following code is only for tcp4 */
  14.464 -  psh = pi->header[XN_HDR_SIZE + pi->ip4_header_length + 13] & 8;
  14.465 -  while (pi->tcp_remaining)
  14.466 -  {
  14.467 -    if (!XenNet_MakePacket(xi, rc, pi))
  14.468 -    {
  14.469 -      KdPrint((__DRIVER_NAME "     Ran out of packets\n"));
  14.470 -      xi->stats.ifInDiscards++;
  14.471 -      break; /* we are out of memory - just drop the packets */
  14.472 -    }
  14.473 -    if (psh)
  14.474 -    {
  14.475 -      //NdisGetFirstBufferFromPacketSafe(packet, &mdl, &header_va, &buffer_length, &total_length, NormalPagePriority);
  14.476 -      if (pi->tcp_remaining)
  14.477 -        pi->header[XN_HDR_SIZE + pi->ip4_header_length + 13] &= ~8;
  14.478 -      else
  14.479 -        pi->header[XN_HDR_SIZE + pi->ip4_header_length + 13] |= 8;
  14.480 -    }
  14.481 -    //XenNet_SumPacketData(pi, packet, TRUE);
  14.482 -    //entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
  14.483 -    //InsertTailList(rx_packet_list, entry);
  14.484 -  }
  14.485 -done:
  14.486 -  page_buf = pi->first_pb;
  14.487 -  while (page_buf)
  14.488 -  {
  14.489 -    shared_buffer_t *next_pb = page_buf->next;
  14.490 -    put_pb_on_freelist(xi, page_buf); /* this doesn't actually free the page_puf if there are outstanding references */
  14.491 -    page_buf = next_pb;
  14.492 -  }
  14.493 -  XenNet_ClearPacketInfo(pi);
  14.494 -  //FUNCTION_EXIT();
  14.495 -  return;
  14.496 -}
  14.497 -
  14.498 -/* called at <= DISPATCH_LEVEL */
  14.499 -/* it's okay for return packet to be called while resume_state != RUNNING as the packet will simply be added back to the freelist, the grants will be fixed later */
  14.500 -VOID
  14.501 -XenNet_ReturnNetBufferLists(NDIS_HANDLE adapter_context, PNET_BUFFER_LIST curr_nbl, ULONG return_flags)
  14.502 -{
  14.503 -  struct xennet_info *xi = adapter_context;
  14.504 -  UNREFERENCED_PARAMETER(return_flags);
  14.505 -
  14.506 -  //FUNCTION_ENTER();
  14.507 -
  14.508 -  //KdPrint((__DRIVER_NAME "     page_buf = %p\n", page_buf));
  14.509 -
  14.510 -  NT_ASSERT(xi);
  14.511 -  while (curr_nbl)
  14.512 -  {
  14.513 -    PNET_BUFFER_LIST next_nbl;
  14.514 -    PNET_BUFFER curr_nb;
  14.515 -    
  14.516 -    next_nbl = NET_BUFFER_LIST_NEXT_NBL(curr_nbl);
  14.517 -    curr_nb = NET_BUFFER_LIST_FIRST_NB(curr_nbl);
  14.518 -    while (curr_nb)
  14.519 -    {
  14.520 -      PNET_BUFFER next_nb;
  14.521 -      PMDL curr_mdl;
  14.522 -      shared_buffer_t *page_buf;
  14.523 -      
  14.524 -      next_nb = NET_BUFFER_NEXT_NB(curr_nb);
  14.525 -      curr_mdl = NET_BUFFER_FIRST_MDL(curr_nb);
  14.526 -      page_buf = NB_FIRST_PB(curr_nb);
  14.527 -      while (curr_mdl)
  14.528 -      {
  14.529 -        shared_buffer_t *next_buf;
  14.530 -        PMDL next_mdl;
  14.531 -        
  14.532 -        NT_ASSERT(page_buf); /* make sure that there is a pb to match this mdl */
  14.533 -        next_mdl = curr_mdl->Next;
  14.534 -        next_buf = page_buf->next;
  14.535 -        if (!page_buf->virtual)
  14.536 -        {
  14.537 -          /* this is a hb not a pb because virtual is NULL (virtual is just the memory after the hb */
  14.538 -          put_hb_on_freelist(xi, (shared_buffer_t *)MmGetMdlVirtualAddress(curr_mdl) - 1);
  14.539 -        }
  14.540 -        else
  14.541 -        {
  14.542 -          //KdPrint((__DRIVER_NAME "     returning page_buf %p with id %d\n", page_buf, page_buf->id));
  14.543 -          if (curr_mdl != page_buf->mdl)
  14.544 -          {
  14.545 -            //KdPrint((__DRIVER_NAME "     curr_mdl = %p, page_buf->mdl = %p\n", curr_mdl, page_buf->mdl));
  14.546 -            IoFreeMdl(curr_mdl);
  14.547 -          }
  14.548 -          put_pb_on_freelist(xi, page_buf);
  14.549 -        }
  14.550 -        curr_mdl = next_mdl;
  14.551 -        page_buf = next_buf;
  14.552 -      }
  14.553 -
  14.554 -      NdisFreeNetBuffer(curr_nb);
  14.555 -      InterlockedDecrement(&xi->rx_outstanding);
  14.556 -
  14.557 -      curr_nb = next_nb;
  14.558 -    }
  14.559 -    NdisFreeNetBufferList(curr_nbl);
  14.560 -    curr_nbl = next_nbl;
  14.561 -  }
  14.562 -  
  14.563 -  if (!xi->rx_outstanding && xi->device_state != DEVICE_STATE_ACTIVE)
  14.564 -    KeSetEvent(&xi->rx_idle_event, IO_NO_INCREMENT, FALSE);
  14.565 -
  14.566 -  //FUNCTION_EXIT();
  14.567 -}
  14.568 -
  14.569 -/* We limit the number of packets per interrupt so that acks get a chance
  14.570 -under high rx load. The DPC is immediately re-scheduled */
  14.571 -//#define MAXIMUM_PACKETS_PER_INTERRUPT 32 /* this is calculated before large packet split */
  14.572 -//#define MAXIMUM_DATA_PER_INTERRUPT (MAXIMUM_PACKETS_PER_INTERRUPT * 1500) /* help account for large packets */
  14.573 -
  14.574 -#define MAXIMUM_PACKETS_PER_INTERRUPT 2560 /* this is calculated before large packet split */
  14.575 -#define MAXIMUM_DATA_PER_INTERRUPT (MAXIMUM_PACKETS_PER_INTERRUPT * 1500) /* help account for large packets */
  14.576 -
  14.577 -// Called at DISPATCH_LEVEL
  14.578 -BOOLEAN
  14.579 -XenNet_RxBufferCheck(struct xennet_info *xi)
  14.580 -{
  14.581 -  RING_IDX cons, prod;
  14.582 -  ULONG packet_count = 0;
  14.583 -  ULONG packet_data = 0;
  14.584 -  ULONG buffer_count = 0;
  14.585 -  USHORT id;
  14.586 -  int more_to_do = FALSE;
  14.587 -  shared_buffer_t *page_buf;
  14.588 -  //LIST_ENTRY rx_header_only_packet_list;
  14.589 -  //PLIST_ENTRY entry;
  14.590 -  //ULONG nbl_count = 0;
  14.591 -  ULONG interim_packet_data = 0;
  14.592 -  struct netif_extra_info *ei;
  14.593 -  rx_context_t rc;
  14.594 -  packet_info_t *pi = &xi->rxpi[KeGetCurrentProcessorNumber() & 0xff];
  14.595 -  shared_buffer_t *head_buf = NULL;
  14.596 -  shared_buffer_t *tail_buf = NULL;
  14.597 -  shared_buffer_t *last_buf = NULL;
  14.598 -  BOOLEAN extra_info_flag = FALSE;
  14.599 -  BOOLEAN more_data_flag = FALSE;
  14.600 -  BOOLEAN dont_set_event;
  14.601 -  //FUNCTION_ENTER();
  14.602 -
  14.603 -  rc.first_nbl = NULL;
  14.604 -  rc.last_nbl = NULL;
  14.605 -  rc.packet_count = 0;
  14.606 -  rc.nbl_count = 0;
  14.607 -  
  14.608 -  /* get all the buffers off the ring as quickly as possible so the lock is held for a minimum amount of time */
  14.609 -  KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
  14.610 -  
  14.611 -  if (xi->device_state != DEVICE_STATE_ACTIVE) {
  14.612 -    /* there is a chance that our Dpc had been queued just before the shutdown... */
  14.613 -    KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
  14.614 -    return FALSE;
  14.615 -  }
  14.616 -
  14.617 -  if (xi->rx_partial_buf) {
  14.618 -    head_buf = xi->rx_partial_buf;
  14.619 -    tail_buf = xi->rx_partial_buf;
  14.620 -    while (tail_buf->next)
  14.621 -      tail_buf = tail_buf->next;
  14.622 -    more_data_flag = xi->rx_partial_more_data_flag;
  14.623 -    extra_info_flag = xi->rx_partial_extra_info_flag;
  14.624 -    xi->rx_partial_buf = NULL;
  14.625 -  }
  14.626 -
  14.627 -  do {
  14.628 -    prod = xi->rx_ring.sring->rsp_prod;
  14.629 -    KeMemoryBarrier(); /* Ensure we see responses up to 'prod'. */
  14.630 -
  14.631 -    for (cons = xi->rx_ring.rsp_cons; cons != prod && packet_count < MAXIMUM_PACKETS_PER_INTERRUPT && packet_data < MAXIMUM_DATA_PER_INTERRUPT; cons++) {
  14.632 -      id = (USHORT)(cons & (NET_RX_RING_SIZE - 1));
  14.633 -      page_buf = xi->rx_ring_pbs[id];
  14.634 -      NT_ASSERT(page_buf);
  14.635 -      xi->rx_ring_pbs[id] = NULL;
  14.636 -      xi->rx_id_free++;
  14.637 -      memcpy(&page_buf->rsp, RING_GET_RESPONSE(&xi->rx_ring, cons), max(sizeof(struct netif_rx_response), sizeof(struct netif_extra_info)));
  14.638 -      if (!extra_info_flag) {
  14.639 -        if (page_buf->rsp.status <= 0 || page_buf->rsp.offset + page_buf->rsp.status > PAGE_SIZE) {
  14.640 -          KdPrint((__DRIVER_NAME "     Error: rsp offset %d, size %d\n",
  14.641 -            page_buf->rsp.offset, page_buf->rsp.status));
  14.642 -          NT_ASSERT(!extra_info_flag);
  14.643 -          put_pb_on_freelist(xi, page_buf);
  14.644 -          continue;
  14.645 -        }
  14.646 -      }
  14.647 -      
  14.648 -      if (!head_buf) {
  14.649 -        head_buf = page_buf;
  14.650 -        tail_buf = page_buf;
  14.651 -      } else {
  14.652 -        tail_buf->next = page_buf;
  14.653 -        tail_buf = page_buf;
  14.654 -      }
  14.655 -      page_buf->next = NULL;
  14.656 -
  14.657 -      if (extra_info_flag) {
  14.658 -        ei = (struct netif_extra_info *)&page_buf->rsp;
  14.659 -        extra_info_flag = ei->flags & XEN_NETIF_EXTRA_FLAG_MORE;
  14.660 -      } else {
  14.661 -        more_data_flag = (BOOLEAN)(page_buf->rsp.flags & NETRXF_more_data);
  14.662 -        extra_info_flag = (BOOLEAN)(page_buf->rsp.flags & NETRXF_extra_info);
  14.663 -        interim_packet_data += page_buf->rsp.status;
  14.664 -      }
  14.665 -      
  14.666 -      if (!extra_info_flag && !more_data_flag) {
  14.667 -        last_buf = page_buf;
  14.668 -        packet_count++;
  14.669 -        packet_data += interim_packet_data;
  14.670 -        interim_packet_data = 0;
  14.671 -        }
  14.672 -      buffer_count++;
  14.673 -    }
  14.674 -    xi->rx_ring.rsp_cons = cons;
  14.675 -
  14.676 -    /* Give netback more buffers */
  14.677 -    XenNet_FillRing(xi);
  14.678 -
  14.679 -    if (packet_count >= MAXIMUM_PACKETS_PER_INTERRUPT || packet_data >= MAXIMUM_DATA_PER_INTERRUPT)
  14.680 -      break;
  14.681 -
  14.682 -    more_to_do = RING_HAS_UNCONSUMED_RESPONSES(&xi->rx_ring);
  14.683 -    if (!more_to_do) {
  14.684 -      xi->rx_ring.sring->rsp_event = xi->rx_ring.rsp_cons + 1;
  14.685 -      KeMemoryBarrier();
  14.686 -      more_to_do = RING_HAS_UNCONSUMED_RESPONSES(&xi->rx_ring);
  14.687 -    }
  14.688 -  } while (more_to_do);
  14.689 -  
  14.690 -  /* anything past last_buf belongs to an incomplete packet... */
  14.691 -  if (last_buf && last_buf->next)
  14.692 -  {
  14.693 -    KdPrint((__DRIVER_NAME "     Partial receive\n"));
  14.694 -    xi->rx_partial_buf = last_buf->next;
  14.695 -    xi->rx_partial_more_data_flag = more_data_flag;
  14.696 -    xi->rx_partial_extra_info_flag = extra_info_flag;
  14.697 -    last_buf->next = NULL;
  14.698 -  }
  14.699 -
  14.700 -  KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
  14.701 -
  14.702 -  if (packet_count >= MAXIMUM_PACKETS_PER_INTERRUPT || packet_data >= MAXIMUM_DATA_PER_INTERRUPT)
  14.703 -  {
  14.704 -    /* fire again immediately */
  14.705 -    KdPrint((__DRIVER_NAME "     Dpc Duration Exceeded\n"));
  14.706 -    /* we want the Dpc on the end of the queue. By definition we are already on the right CPU so we know the Dpc queue will be run immediately */
  14.707 -//    KeSetImportanceDpc(&xi->rxtx_dpc, MediumImportance);
  14.708 -    KeInsertQueueDpc(&xi->rxtx_dpc, NULL, NULL);
  14.709 -    /* dont set an event in TX path */
  14.710 -    dont_set_event = TRUE;
  14.711 -  }
  14.712 -  else
  14.713 -  {
  14.714 -    /* make sure the Dpc queue is run immediately next interrupt */
  14.715 -//    KeSetImportanceDpc(&xi->rxtx_dpc, HighImportance);
  14.716 -    /* set an event in TX path */
  14.717 -    dont_set_event = FALSE;
  14.718 -  }
  14.719 -
  14.720 -  /* make packets out of the buffers */
  14.721 -  page_buf = head_buf;
  14.722 -  extra_info_flag = FALSE;
  14.723 -  more_data_flag = FALSE;
  14.724 -
  14.725 -  while (page_buf)
  14.726 -  {
  14.727 -    shared_buffer_t *next_buf = page_buf->next;
  14.728 -    PMDL mdl;
  14.729 -
  14.730 -    page_buf->next = NULL;
  14.731 -    if (extra_info_flag)
  14.732 -    {
  14.733 -      //KdPrint((__DRIVER_NAME "     processing extra info\n"));
  14.734 -      ei = (struct netif_extra_info *)&page_buf->rsp;
  14.735 -      extra_info_flag = ei->flags & XEN_NETIF_EXTRA_FLAG_MORE;
  14.736 -      switch (ei->type)
  14.737 -      {
  14.738 -      case XEN_NETIF_EXTRA_TYPE_GSO:
  14.739 -        switch (ei->u.gso.type)
  14.740 -        {
  14.741 -        case XEN_NETIF_GSO_TYPE_TCPV4:
  14.742 -          pi->mss = ei->u.gso.size;
  14.743 -          //KdPrint((__DRIVER_NAME "     mss = %d\n", pi->mss));
  14.744 -          // TODO - put this assertion somewhere NT_ASSERT(header_len + pi->mss <= PAGE_SIZE); // this limits MTU to PAGE_SIZE - XN_HEADER_LEN
  14.745 -          break;
  14.746 -        default:
  14.747 -          KdPrint((__DRIVER_NAME "     Unknown GSO type (%d) detected\n", ei->u.gso.type));
  14.748 -          break;
  14.749 -        }
  14.750 -        break;
  14.751 -      default:
  14.752 -        KdPrint((__DRIVER_NAME "     Unknown extra info type (%d) detected\n", ei->type));
  14.753 -        break;
  14.754 -      }
  14.755 -      put_pb_on_freelist(xi, page_buf);
  14.756 -    }
  14.757 -    else
  14.758 -    {
  14.759 -      NT_ASSERT(!page_buf->rsp.offset);
  14.760 -      if (!more_data_flag) // handling the packet's 1st buffer
  14.761 -      {
  14.762 -        if (page_buf->rsp.flags & NETRXF_csum_blank)
  14.763 -          pi->csum_blank = TRUE;
  14.764 -        if (page_buf->rsp.flags & NETRXF_data_validated)
  14.765 -          pi->data_validated = TRUE;
  14.766 -      }
  14.767 -      mdl = page_buf->mdl;
  14.768 -      mdl->ByteCount = page_buf->rsp.status; //NdisAdjustBufferLength(mdl, page_buf->rsp.status);
  14.769 -      //KdPrint((__DRIVER_NAME "     buffer = %p, pb = %p\n", buffer, page_buf));
  14.770 -      if (pi->first_pb)
  14.771 -      {
  14.772 -        NT_ASSERT(pi->curr_pb);
  14.773 -        //KdPrint((__DRIVER_NAME "     additional buffer\n"));
  14.774 -        pi->curr_pb->next = page_buf;
  14.775 -        pi->curr_pb = page_buf;
  14.776 -        NT_ASSERT(pi->curr_mdl);
  14.777 -        pi->curr_mdl->Next = mdl;
  14.778 -        pi->curr_mdl = mdl;
  14.779 -      }
  14.780 -      else
  14.781 -      {
  14.782 -        pi->first_pb = page_buf;
  14.783 -        pi->curr_pb = page_buf;
  14.784 -        pi->first_mdl = mdl;
  14.785 -        pi->curr_mdl = mdl;
  14.786 -      }
  14.787 -      //pi->mdl_count++;
  14.788 -      extra_info_flag = (BOOLEAN)(page_buf->rsp.flags & NETRXF_extra_info);
  14.789 -      more_data_flag = (BOOLEAN)(page_buf->rsp.flags & NETRXF_more_data);
  14.790 -      pi->total_length = pi->total_length + page_buf->rsp.status;
  14.791 -    }
  14.792 -
  14.793 -    /* Packet done, add it to the list */
  14.794 -    if (!more_data_flag && !extra_info_flag)
  14.795 -    {
  14.796 -      pi->curr_pb = pi->first_pb;
  14.797 -      pi->curr_mdl = pi->first_mdl;
  14.798 -      XenNet_MakePackets(xi, &rc, pi);
  14.799 -    }
  14.800 -
  14.801 -    page_buf = next_buf;
  14.802 -  }
  14.803 -  NT_ASSERT(!more_data_flag && !extra_info_flag);
  14.804 -
  14.805 -  if (rc.first_nbl)
  14.806 -  {
  14.807 -    NdisMIndicateReceiveNetBufferLists(xi->adapter_handle, rc.first_nbl,
  14.808 -      NDIS_DEFAULT_PORT_NUMBER, rc.nbl_count,
  14.809 -      NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL
  14.810 -      //| NDIS_RECEIVE_FLAGS_SINGLE_ETHER_TYPE 
  14.811 -      | NDIS_RECEIVE_FLAGS_PERFECT_FILTERED);
  14.812 -  }
  14.813 -  //FUNCTION_EXIT();
  14.814 -  return dont_set_event;
  14.815 -}
  14.816 -
  14.817 -static VOID
  14.818 -XenNet_BufferFree(xennet_info_t *xi)
  14.819 -{
  14.820 -  shared_buffer_t *sb;
  14.821 -  int i;
  14.822 -
  14.823 -  for (i = 0; i < NET_RX_RING_SIZE; i++) {
  14.824 -    if (xi->rx_ring_pbs[i] != NULL) {
  14.825 -      put_pb_on_freelist(xi, xi->rx_ring_pbs[i]);
  14.826 -      xi->rx_ring_pbs[i] = NULL;
  14.827 -    }
  14.828 -  }
  14.829 -
  14.830 -  /* because we are shutting down this won't allocate new ones */
  14.831 -  while ((sb = get_pb_from_freelist(xi)) != NULL) {
  14.832 -    XnEndAccess(xi->handle,
  14.833 -        sb->gref, FALSE, (ULONG)'XNRX');
  14.834 -    IoFreeMdl(sb->mdl);
  14.835 -    NdisFreeMemory(sb->virtual, sizeof(shared_buffer_t), 0);
  14.836 -    NdisFreeMemory(sb, PAGE_SIZE, 0);
  14.837 -  }
  14.838 -  while ((sb = get_hb_from_freelist(xi)) != NULL) {
  14.839 -    IoFreeMdl(sb->mdl);
  14.840 -    NdisFreeMemory(sb, sizeof(shared_buffer_t) + MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH, 0);
  14.841 -  }
  14.842 -}
  14.843 -
  14.844 -BOOLEAN
  14.845 -XenNet_RxInit(xennet_info_t *xi)
  14.846 -{
  14.847 -  NET_BUFFER_LIST_POOL_PARAMETERS nbl_pool_parameters;
  14.848 -  NET_BUFFER_POOL_PARAMETERS nb_pool_parameters;
  14.849 -  int ret;
  14.850 -  int i;
  14.851 -  
  14.852 -  FUNCTION_ENTER();
  14.853 -
  14.854 -  // this stuff needs to be done once only...
  14.855 -  KeInitializeSpinLock(&xi->rx_lock);
  14.856 -  KeInitializeEvent(&xi->packet_returned_event, SynchronizationEvent, FALSE);
  14.857 -  xi->rxpi = NdisAllocateMemoryWithTagPriority(xi->adapter_handle, sizeof(packet_info_t) * NdisSystemProcessorCount(), XENNET_POOL_TAG, NormalPoolPriority);
  14.858 -  if (!xi->rxpi) {
  14.859 -    KdPrint(("NdisAllocateMemoryWithTagPriority failed\n"));
  14.860 -    return FALSE;
  14.861 -  }
  14.862 -  NdisZeroMemory(xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount());
  14.863 -
  14.864 -  ret = stack_new(&xi->rx_pb_stack, NET_RX_RING_SIZE * 4);
  14.865 -  if (!ret) {
  14.866 -    FUNCTION_MSG("Failed to allocate rx_pb_stack\n");
  14.867 -    NdisFreeMemory(xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount(), 0);
  14.868 -    return FALSE;
  14.869 -  }
  14.870 -  stack_new(&xi->rx_hb_stack, NET_RX_RING_SIZE * 4);
  14.871 -  if (!ret) {
  14.872 -    FUNCTION_MSG("Failed to allocate rx_hb_stack\n");
  14.873 -    stack_delete(xi->rx_pb_stack, NULL, NULL);
  14.874 -    NdisFreeMemory(xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount(), 0);
  14.875 -    return FALSE;
  14.876 -  }
  14.877 -
  14.878 -  xi->rx_id_free = NET_RX_RING_SIZE;
  14.879 -  xi->rx_outstanding = 0;
  14.880 -
  14.881 -  for (i = 0; i < NET_RX_RING_SIZE; i++) {
  14.882 -    xi->rx_ring_pbs[i] = NULL;
  14.883 -  }
  14.884 -  
  14.885 -  nbl_pool_parameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
  14.886 -  nbl_pool_parameters.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
  14.887 -  nbl_pool_parameters.Header.Size = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
  14.888 -  nbl_pool_parameters.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT;
  14.889 -  nbl_pool_parameters.fAllocateNetBuffer = FALSE;
  14.890 -  nbl_pool_parameters.ContextSize = 0;
  14.891 -  nbl_pool_parameters.PoolTag = XENNET_POOL_TAG;
  14.892 -  nbl_pool_parameters.DataSize = 0; /* NET_BUFFERS are always allocated separately */
  14.893 -  
  14.894 -  xi->rx_nbl_pool = NdisAllocateNetBufferListPool(xi->adapter_handle, &nbl_pool_parameters);
  14.895 -  if (!xi->rx_nbl_pool) {
  14.896 -    KdPrint(("NdisAllocateNetBufferListPool failed\n"));
  14.897 -    return FALSE;
  14.898 -  }
  14.899 -
  14.900 -  nb_pool_parameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
  14.901 -  nb_pool_parameters.Header.Revision = NET_BUFFER_POOL_PARAMETERS_REVISION_1;
  14.902 -  nb_pool_parameters.Header.Size = NDIS_SIZEOF_NET_BUFFER_POOL_PARAMETERS_REVISION_1;
  14.903 -  nb_pool_parameters.PoolTag = XENNET_POOL_TAG;
  14.904 -  nb_pool_parameters.DataSize = 0; /* the buffers come from the ring */
  14.905 -  xi->rx_nb_pool = NdisAllocateNetBufferPool(xi->adapter_handle, &nb_pool_parameters);
  14.906 -  if (!xi->rx_nb_pool) {
  14.907 -    KdPrint(("NdisAllocateNetBufferPool (rx_nb_pool) failed\n"));
  14.908 -    return FALSE;
  14.909 -  }
  14.910 -
  14.911 -  XenNet_FillRing(xi);
  14.912 -
  14.913 -  FUNCTION_EXIT();
  14.914 -
  14.915 -  return TRUE;
  14.916 -}
  14.917 -
  14.918 -VOID
  14.919 -XenNet_RxShutdown(xennet_info_t *xi) {
  14.920 -  KIRQL old_irql;
  14.921 -  UNREFERENCED_PARAMETER(xi);
  14.922 -
  14.923 -  FUNCTION_ENTER();
  14.924 -
  14.925 -  KeAcquireSpinLock(&xi->rx_lock, &old_irql);
  14.926 -  while (xi->rx_outstanding) {
  14.927 -    KdPrint((__DRIVER_NAME "     Waiting for all packets to be returned\n"));
  14.928 -    KeReleaseSpinLock(&xi->rx_lock, old_irql);
  14.929 -    KeWaitForSingleObject(&xi->rx_idle_event, Executive, KernelMode, FALSE, NULL);
  14.930 -    KeAcquireSpinLock(&xi->rx_lock, &old_irql);
  14.931 -  }
  14.932 -  KeReleaseSpinLock(&xi->rx_lock, old_irql);
  14.933 -  
  14.934 -  XenNet_BufferFree(xi);
  14.935 -
  14.936 -  stack_delete(xi->rx_pb_stack, NULL, NULL);
  14.937 -  stack_delete(xi->rx_hb_stack, NULL, NULL);
  14.938 -  
  14.939 -  NdisFreeMemory(xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount(), 0);
  14.940 -
  14.941 -  NdisFreeNetBufferPool(xi->rx_nb_pool);
  14.942 -  NdisFreeNetBufferListPool(xi->rx_nbl_pool);
  14.943 -
  14.944 -  FUNCTION_EXIT();
  14.945 -  return;
  14.946 -}
    15.1 --- a/xennet/xennet6_tx.c	Sun Feb 10 23:12:03 2013 +1100
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,767 +0,0 @@
    15.4 -/*
    15.5 -PV Net Driver for Windows Xen HVM Domains
    15.6 -Copyright (C) 2007 James Harper
    15.7 -Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
    15.8 -
    15.9 -This program is free software; you can redistribute it and/or
   15.10 -modify it under the terms of the GNU General Public License
   15.11 -as published by the Free Software Foundation; either version 2
   15.12 -of the License, or (at your option) any later version.
   15.13 -
   15.14 -This program is distributed in the hope that it will be useful,
   15.15 -but WITHOUT ANY WARRANTY; without even the implied warranty of
   15.16 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15.17 -GNU General Public License for more details.
   15.18 -
   15.19 -You should have received a copy of the GNU General Public License
   15.20 -along with this program; if not, write to the Free Software
   15.21 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   15.22 -*/
   15.23 -
   15.24 -#include "xennet6.h"
   15.25 -
   15.26 -static USHORT
   15.27 -get_id_from_freelist(struct xennet_info *xi)
   15.28 -{
   15.29 -  NT_ASSERT(xi->tx_id_free);
   15.30 -  xi->tx_id_free--;
   15.31 -
   15.32 -  return xi->tx_id_list[xi->tx_id_free];
   15.33 -}
   15.34 -
   15.35 -static VOID
   15.36 -put_id_on_freelist(struct xennet_info *xi, USHORT id)
   15.37 -{
   15.38 -  xi->tx_id_list[xi->tx_id_free] = id;
   15.39 -  xi->tx_id_free++;
   15.40 -}
   15.41 -
   15.42 -#define SWAP_USHORT(x) (USHORT)((((x & 0xFF) << 8)|((x >> 8) & 0xFF)))
   15.43 -
   15.44 -static __forceinline struct netif_tx_request *
   15.45 -XenNet_PutCbOnRing(struct xennet_info *xi, PVOID coalesce_buf, ULONG length, grant_ref_t gref)
   15.46 -{
   15.47 -  struct netif_tx_request *tx;
   15.48 -  tx = RING_GET_REQUEST(&xi->tx_ring, xi->tx_ring.req_prod_pvt);
   15.49 -  xi->tx_ring.req_prod_pvt++;
   15.50 -  xi->tx_ring_free--;
   15.51 -  tx->id = get_id_from_freelist(xi);
   15.52 -  NT_ASSERT(xi->tx_shadows[tx->id].gref == INVALID_GRANT_REF);
   15.53 -  NT_ASSERT(!xi->tx_shadows[tx->id].cb);
   15.54 -  xi->tx_shadows[tx->id].cb = coalesce_buf;
   15.55 -  tx->gref = XnGrantAccess(xi->handle, (ULONG)(MmGetPhysicalAddress(coalesce_buf).QuadPart >> PAGE_SHIFT), FALSE, gref, (ULONG)'XNTX');
   15.56 -  xi->tx_shadows[tx->id].gref = tx->gref;
   15.57 -  tx->offset = 0;
   15.58 -  tx->size = (USHORT)length;
   15.59 -  NT_ASSERT(tx->offset + tx->size <= PAGE_SIZE);
   15.60 -  NT_ASSERT(tx->size);
   15.61 -  return tx;
   15.62 -}
   15.63 -  
   15.64 -/* Called at DISPATCH_LEVEL with tx_lock held */
   15.65 -/*
   15.66 - * Send one NDIS_PACKET. This may involve multiple entries on TX ring.
   15.67 - */
   15.68 -static BOOLEAN
   15.69 -XenNet_HWSendPacket(struct xennet_info *xi, PNET_BUFFER nb)
   15.70 -{
   15.71 -  struct netif_tx_request *tx0 = NULL;
   15.72 -  struct netif_tx_request *txN = NULL;
   15.73 -  struct netif_extra_info *ei = NULL;
   15.74 -  NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO lso_info;
   15.75 -  ULONG mss = 0;
   15.76 -  NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csum_info;
   15.77 -  uint16_t flags = NETTXF_more_data;
   15.78 -  packet_info_t pi;
   15.79 -  BOOLEAN ndis_lso = FALSE;
   15.80 -  BOOLEAN xen_gso = FALSE;
   15.81 -  ULONG remaining;
   15.82 -  ULONG frags = 0;
   15.83 -  BOOLEAN coalesce_required = FALSE;
   15.84 -  PVOID coalesce_buf;
   15.85 -  ULONG coalesce_remaining = 0;
   15.86 -  grant_ref_t gref;
   15.87 -  ULONG tx_length = 0;
   15.88 -  
   15.89 -  //FUNCTION_ENTER();
   15.90 -
   15.91 -  gref = XnAllocateGrant(xi->handle, (ULONG)'XNTX');
   15.92 -  if (gref == INVALID_GRANT_REF)
   15.93 -  {
   15.94 -    FUNCTION_MSG("out of grefs\n");
   15.95 -    return FALSE;
   15.96 -  }
   15.97 -  coalesce_buf = NdisAllocateFromNPagedLookasideList(&xi->tx_lookaside_list);
   15.98 -  if (!coalesce_buf)
   15.99 -  {
  15.100 -    XnFreeGrant(xi->handle, gref, (ULONG)'XNTX');
  15.101 -    FUNCTION_MSG("out of memory\n");
  15.102 -    return FALSE;
  15.103 -  }
  15.104 -  XenNet_ClearPacketInfo(&pi);
  15.105 -  //NdisQueryPacket(packet, NULL, (PUINT)&pi.mdl_count, &pi.first_buffer, (PUINT)&pi.total_length);
  15.106 -  /* create a new MDL over the data portion of the first MDL in the packet... it's just easier this way */
  15.107 -  IoBuildPartialMdl(nb->CurrentMdl,
  15.108 -    &pi.first_mdl_storage,
  15.109 -    (PUCHAR)MmGetMdlVirtualAddress(nb->CurrentMdl) + nb->CurrentMdlOffset,
  15.110 -    MmGetMdlByteCount(nb->CurrentMdl) - nb->CurrentMdlOffset);
  15.111 -  pi.first_mdl_storage.Next = nb->CurrentMdl->Next;
  15.112 -  pi.first_mdl = pi.curr_mdl = &pi.first_mdl_storage;
  15.113 -  pi.first_mdl_offset = pi.curr_mdl_offset = 0;
  15.114 -  pi.total_length = nb->DataLength;
  15.115 -  remaining = min(pi.total_length, PAGE_SIZE);
  15.116 -  while (remaining) /* this much gets put in the header */
  15.117 -  {
  15.118 -    ULONG length = XenNet_QueryData(&pi, remaining);
  15.119 -    remaining -= length;
  15.120 -    XenNet_EatData(&pi, length);
  15.121 -  }
  15.122 -  frags++;
  15.123 -  if (pi.total_length > PAGE_SIZE) /* these are the frags we care about */
  15.124 -  {
  15.125 -    remaining = pi.total_length - PAGE_SIZE;
  15.126 -    while (remaining)
  15.127 -    {
  15.128 -      ULONG length = XenNet_QueryData(&pi, PAGE_SIZE);
  15.129 -      if (length != 0)
  15.130 -      {
  15.131 -        frags++;
  15.132 -        if (frags > LINUX_MAX_SG_ELEMENTS)
  15.133 -          break; /* worst case there could be hundreds of fragments - leave the loop now */
  15.134 -      }
  15.135 -      remaining -= length;
  15.136 -      XenNet_EatData(&pi, length);
  15.137 -    }
  15.138 -  }
  15.139 -  if (frags > LINUX_MAX_SG_ELEMENTS)
  15.140 -  {
  15.141 -    frags = LINUX_MAX_SG_ELEMENTS;
  15.142 -    coalesce_required = TRUE;
  15.143 -  }
  15.144 -
  15.145 -  /* if we have enough space on the ring then we have enough id's so no need to check for that */
  15.146 -  if (xi->tx_ring_free < frags + 1) {
  15.147 -    XnFreeGrant(xi->handle, gref, (ULONG)'XNTX');
  15.148 -    NdisFreeToNPagedLookasideList(&xi->tx_lookaside_list, coalesce_buf);
  15.149 -    //FUNCTION_MSG("Full on send - ring full\n");
  15.150 -    return FALSE;
  15.151 -  }
  15.152 -  XenNet_ParsePacketHeader(&pi, coalesce_buf, PAGE_SIZE);
  15.153 -  remaining = pi.total_length - pi.header_length;
  15.154 -  if (pi.ip_version == 4 && pi.ip_proto == 6 && pi.ip4_length == 0)
  15.155 -  {
  15.156 -#if 0  
  15.157 -    PMDL tmp_mdl;
  15.158 -    PUCHAR my_va;
  15.159 -    FUNCTION_MSG("total_length == 0, CurrentMdlOffset == %d\n", nb->CurrentMdlOffset);
  15.160 -    my_va = MmGetMdlVirtualAddress(pi.first_mdl);
  15.161 -    FUNCTION_MSG("  first mdl va = %p, offset = %d, length = %d\n", MmGetMdlVirtualAddress(pi.first_mdl), MmGetMdlByteOffset(pi.first_mdl), MmGetMdlByteCount(pi.first_mdl));
  15.162 -    FUNCTION_MSG("    0010: %02x%02x\n", my_va[0x10], my_va[0x11]);
  15.163 -    for (tmp_mdl = nb->CurrentMdl; tmp_mdl; tmp_mdl = tmp_mdl->Next)
  15.164 -    {
  15.165 -      FUNCTION_MSG("  mdl = %p, va = %p, offset = %d, length = %d\n", tmp_mdl, MmGetMdlVirtualAddress(tmp_mdl), MmGetMdlByteOffset(tmp_mdl), MmGetMdlByteCount(tmp_mdl));
  15.166 -      if (tmp_mdl == nb->CurrentMdl)
  15.167 -      {
  15.168 -        my_va = MmGetSystemAddressForMdlSafe(tmp_mdl, HighPagePriority);
  15.169 -        my_va += nb->CurrentMdlOffset;
  15.170 -        FUNCTION_MSG("    0010: %02x%02x\n", my_va[0x10], my_va[0x11]);
  15.171 -      }
  15.172 -    }
  15.173 -#endif
  15.174 -    *((PUSHORT)(pi.header + 0x10)) = GET_NET_USHORT((USHORT)nb->DataLength - XN_HDR_SIZE);
  15.175 -  }
  15.176 -
  15.177 -  // do we need to check if the packet is tcpip??
  15.178 -  csum_info.Value = NET_BUFFER_LIST_INFO(NB_NBL(nb), TcpIpChecksumNetBufferListInfo);
  15.179 -  if (csum_info.Transmit.IsIPv4)
  15.180 -  {
  15.181 -#if 0
  15.182 -    if (csum_info.Transmit.IpHeaderChecksum && !xi->setting_csum.V4Transmit.IpChecksum)
  15.183 -    {
  15.184 -      KdPrint((__DRIVER_NAME "     IpChecksum not enabled\n"));
  15.185 -      //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
  15.186 -      //return TRUE;
  15.187 -    }
  15.188 -#endif
  15.189 -    if (csum_info.Transmit.TcpChecksum)
  15.190 -    {
  15.191 -      if (1) //xi->setting_csum.V4Transmit.TcpChecksum)
  15.192 -      {
  15.193 -        flags |= NETTXF_csum_blank | NETTXF_data_validated;
  15.194 -      }
  15.195 -      else
  15.196 -      {
  15.197 -        KdPrint((__DRIVER_NAME "     TcpChecksum not enabled\n"));
  15.198 -        //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
  15.199 -        //return TRUE;
  15.200 -      }
  15.201 -    }
  15.202 -    else if (csum_info.Transmit.UdpChecksum)
  15.203 -    {
  15.204 -      if (1) //xi->setting_csum.V4Transmit.UdpChecksum)
  15.205 -      {
  15.206 -        flags |= NETTXF_csum_blank | NETTXF_data_validated;
  15.207 -      }
  15.208 -      else
  15.209 -      {
  15.210 -        KdPrint((__DRIVER_NAME "     UdpChecksum not enabled\n"));
  15.211 -        //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
  15.212 -        //return TRUE;
  15.213 -      }
  15.214 -    }
  15.215 -  }
  15.216 -  else if (csum_info.Transmit.IsIPv6)
  15.217 -  {
  15.218 -    KdPrint((__DRIVER_NAME "     Transmit.IsIPv6 not supported\n"));
  15.219 -    //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
  15.220 -    //return TRUE;
  15.221 -  }
  15.222 -  
  15.223 -  lso_info.Value = NET_BUFFER_LIST_INFO(NB_NBL(nb), TcpLargeSendNetBufferListInfo);
  15.224 -  switch (lso_info.Transmit.Type)
  15.225 -  {
  15.226 -  case NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE:
  15.227 -    mss = lso_info.LsoV1Transmit.MSS;
  15.228 -    /* should make use of TcpHeaderOffset too... maybe just assert if it's not what we expect */
  15.229 -    break;
  15.230 -  case NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE:
  15.231 -    mss = lso_info.LsoV2Transmit.MSS;
  15.232 -    /* should make use of TcpHeaderOffset too... maybe just assert if it's not what we expect */
  15.233 -    break;
  15.234 -  }
  15.235 -  if (mss && pi.parse_result == PARSE_OK)
  15.236 -  {
  15.237 -    //FUNCTION_MSG("lso mss = %d\n", mss);
  15.238 -    //if (NDIS_GET_PACKET_PROTOCOL_TYPE(packet) != NDIS_PROTOCOL_ID_TCP_IP)
  15.239 -    //{
  15.240 -    //  KdPrint((__DRIVER_NAME "     mss specified when packet is not NDIS_PROTOCOL_ID_TCP_IP\n"));
  15.241 -    //}
  15.242 -    ndis_lso = TRUE;
  15.243 -    #if 0
  15.244 -    if (mss > xi->current_lso_ipv4)
  15.245 -    {
  15.246 -      KdPrint((__DRIVER_NAME "     Requested MSS (%d) larger than allowed MSS (%d)\n", mss, xi->current_lso_ipv4));
  15.247 -      //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
  15.248 -      //FUNCTION_EXIT();
  15.249 -      return TRUE;
  15.250 -    }
  15.251 -    #endif
  15.252 -  }
  15.253 -
  15.254 -  if (ndis_lso)
  15.255 -  {    
  15.256 -    flags |= NETTXF_csum_blank | NETTXF_data_validated; /* these may be implied but not specified when lso is used*/
  15.257 -    if (pi.tcp_length >= mss)
  15.258 -    {
  15.259 -      flags |= NETTXF_extra_info;
  15.260 -      xen_gso = TRUE;
  15.261 -    }
  15.262 -    else
  15.263 -    {
  15.264 -      KdPrint((__DRIVER_NAME "     large send specified when tcp_length < mss\n"));
  15.265 -    }
  15.266 -  }
  15.267 -/*
  15.268 -* See io/netif.h. Must put (A) 1st request, then (B) optional extra_info, then
  15.269 -* (C) rest of requests on the ring. Only (A) has csum flags.
  15.270 -*/
  15.271 -
  15.272 -  /* (A) */
  15.273 -  tx0 = XenNet_PutCbOnRing(xi, coalesce_buf, pi.header_length, gref);
  15.274 -  NT_ASSERT(tx0); /* this will never happen */
  15.275 -  tx0->flags = flags;
  15.276 -  tx_length += pi.header_length;
  15.277 -
  15.278 -  /* lso implies IpHeaderChecksum */
  15.279 -  if (ndis_lso || csum_info.Transmit.IpHeaderChecksum)
  15.280 -  {
  15.281 -    XenNet_SumIpHeader(coalesce_buf, pi.ip4_header_length);
  15.282 -  }
  15.283 -  txN = tx0;
  15.284 -
  15.285 -  /* (B) */
  15.286 -  if (xen_gso)
  15.287 -  {
  15.288 -    NT_ASSERT(flags & NETTXF_extra_info);
  15.289 -    ei = (struct netif_extra_info *)RING_GET_REQUEST(&xi->tx_ring, xi->tx_ring.req_prod_pvt);
  15.290 -    //KdPrint((__DRIVER_NAME "     pos = %d\n", xi->tx_ring.req_prod_pvt));
  15.291 -    xi->tx_ring.req_prod_pvt++;
  15.292 -    xi->tx_ring_free--;
  15.293 -    ei->type = XEN_NETIF_EXTRA_TYPE_GSO;
  15.294 -    ei->flags = 0;
  15.295 -    ei->u.gso.size = (USHORT)mss;
  15.296 -    ei->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4;
  15.297 -    ei->u.gso.pad = 0;
  15.298 -    ei->u.gso.features = 0;
  15.299 -  }
  15.300 -
  15.301 -  NT_ASSERT(xi->current_sg_supported || !remaining);
  15.302 -  
  15.303 -  /* (C) - only if data is remaining */
  15.304 -  coalesce_buf = NULL;
  15.305 -  while (remaining > 0)
  15.306 -  {
  15.307 -    ULONG length;
  15.308 -    PFN_NUMBER pfn;
  15.309 -    
  15.310 -    NT_ASSERT(pi.curr_mdl);
  15.311 -    if (coalesce_required)
  15.312 -    {
  15.313 -      PVOID va;
  15.314 -      if (!coalesce_buf)
  15.315 -      {
  15.316 -        gref = XnAllocateGrant(xi->handle, (ULONG)'XNTX');
  15.317 -        if (gref == INVALID_GRANT_REF)
  15.318 -        {
  15.319 -          KdPrint((__DRIVER_NAME "     out of grefs - partial send\n"));
  15.320 -          break;
  15.321 -        }
  15.322 -        coalesce_buf = NdisAllocateFromNPagedLookasideList(&xi->tx_lookaside_list);
  15.323 -        if (!coalesce_buf)
  15.324 -        {
  15.325 -          XnFreeGrant(xi->handle, gref, (ULONG)'XNTX');
  15.326 -          KdPrint((__DRIVER_NAME "     out of memory - partial send\n"));
  15.327 -          break;
  15.328 -        }
  15.329 -        coalesce_remaining = min(PAGE_SIZE, remaining);
  15.330 -      }
  15.331 -      length = XenNet_QueryData(&pi, coalesce_remaining);
  15.332 -      va = NdisBufferVirtualAddressSafe(pi.curr_mdl, LowPagePriority);
  15.333 -      if (!va)
  15.334 -      {
  15.335 -        KdPrint((__DRIVER_NAME "     failed to map buffer va - partial send\n"));
  15.336 -        coalesce_remaining = 0;
  15.337 -        remaining -= min(PAGE_SIZE, remaining);
  15.338 -        NdisFreeToNPagedLookasideList(&xi->tx_lookaside_list, coalesce_buf);
  15.339 -      }
  15.340 -      else
  15.341 -      {
  15.342 -        memcpy((PUCHAR)coalesce_buf + min(PAGE_SIZE, remaining) - coalesce_remaining, (PUCHAR)va + pi.curr_mdl_offset, length);
  15.343 -        coalesce_remaining -= length;
  15.344 -      }
  15.345 -    }
  15.346 -    else
  15.347 -    {
  15.348 -      length = XenNet_QueryData(&pi, PAGE_SIZE);
  15.349 -    }
  15.350 -    if (!length || coalesce_remaining) /* sometimes there are zero length buffers... */
  15.351 -    {
  15.352 -      XenNet_EatData(&pi, length); /* do this so we actually move to the next buffer */
  15.353 -      continue;
  15.354 -    }
  15.355 -
  15.356 -    if (coalesce_buf)
  15.357 -    {
  15.358 -      if (remaining)
  15.359 -      {
  15.360 -        txN = XenNet_PutCbOnRing(xi, coalesce_buf, min(PAGE_SIZE, remaining), gref);
  15.361 -        NT_ASSERT(txN);
  15.362 -        coalesce_buf = NULL;
  15.363 -        tx_length += min(PAGE_SIZE, remaining);
  15.364 -        remaining -= min(PAGE_SIZE, remaining);
  15.365 -      }
  15.366 -    }
  15.367 -    else
  15.368 -    {
  15.369 -      ULONG offset;
  15.370 -      
  15.371 -      gref = XnAllocateGrant(xi->handle, (ULONG)'XNTX');
  15.372 -      if (gref == INVALID_GRANT_REF)
  15.373 -      {
  15.374 -        KdPrint((__DRIVER_NAME "     out of grefs - partial send\n"));
  15.375 -        break;
  15.376 -      }
  15.377 -      txN = RING_GET_REQUEST(&xi->tx_ring, xi->tx_ring.req_prod_pvt);
  15.378 -      xi->tx_ring.req_prod_pvt++;
  15.379 -      xi->tx_ring_free--;
  15.380 -      txN->id = get_id_from_freelist(xi);
  15.381 -      NT_ASSERT(!xi->tx_shadows[txN->id].cb);
  15.382 -      offset = MmGetMdlByteOffset(pi.curr_mdl) + pi.curr_mdl_offset;
  15.383 -      pfn = MmGetMdlPfnArray(pi.curr_mdl)[offset >> PAGE_SHIFT];
  15.384 -      txN->offset = (USHORT)offset & (PAGE_SIZE - 1);
  15.385 -      txN->gref = XnGrantAccess(xi->handle, (ULONG)pfn, FALSE, gref, (ULONG)'XNTX');
  15.386 -      NT_ASSERT(xi->tx_shadows[txN->id].gref == INVALID_GRANT_REF);
  15.387 -      xi->tx_shadows[txN->id].gref = txN->gref;
  15.388 -      //ASSERT(sg->Elements[sg_element].Length > sg_offset);
  15.389 -      txN->size = (USHORT)length;
  15.390 -      NT_ASSERT(txN->offset + txN->size <= PAGE_SIZE);
  15.391 -      NT_ASSERT(txN->size);
  15.392 -      NT_ASSERT(txN->gref != INVALID_GRANT_REF);
  15.393 -      remaining -= length;
  15.394 -      tx_length += length;
  15.395 -    }
  15.396 -    tx0->size = tx0->size + txN->size;
  15.397 -    txN->flags = NETTXF_more_data;
  15.398 -    XenNet_EatData(&pi, length);
  15.399 -  }
  15.400 -  txN->flags &= ~NETTXF_more_data;
  15.401 -  NT_ASSERT(tx0->size == pi.total_length);
  15.402 -  NT_ASSERT(!xi->tx_shadows[txN->id].nb);
  15.403 -  xi->tx_shadows[txN->id].nb = nb;
  15.404 -
  15.405 -  switch (lso_info.Transmit.Type)
  15.406 -  {
  15.407 -  case NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE:
  15.408 -    lso_info.LsoV1TransmitComplete.TcpPayload = tx_length - MAX_ETH_HEADER_LENGTH - pi.ip4_header_length - pi.tcp_header_length;
  15.409 -    break;
  15.410 -  case NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE:
  15.411 -    break;
  15.412 -  }
  15.413 -
  15.414 -  //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
  15.415 -  //FUNCTION_EXIT();
  15.416 -  xi->tx_outstanding++;
  15.417 -//total_sent++;
  15.418 -  //FUNCTION_MSG("sent packet\n");
  15.419 -  return TRUE;
  15.420 -}
  15.421 -
  15.422 -/* Called at DISPATCH_LEVEL with tx_lock held */
  15.423 -static VOID
  15.424 -XenNet_SendQueuedPackets(struct xennet_info *xi)
  15.425 -{
  15.426 -  PLIST_ENTRY nb_entry;
  15.427 -  PNET_BUFFER nb;
  15.428 -  int notify;
  15.429 -
  15.430 -  //FUNCTION_ENTER();
  15.431 -
  15.432 -  if (xi->device_state != DEVICE_STATE_ACTIVE)
  15.433 -    return;
  15.434 -
  15.435 -  while (!IsListEmpty(&xi->tx_waiting_pkt_list)) {
  15.436 -    nb_entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
  15.437 -    nb = CONTAINING_RECORD(nb_entry, NET_BUFFER, NB_LIST_ENTRY_FIELD);
  15.438 -    
  15.439 -    if (!XenNet_HWSendPacket(xi, nb)) {
  15.440 -      //KdPrint((__DRIVER_NAME "     No room for packet\n"));
  15.441 -      InsertHeadList(&xi->tx_waiting_pkt_list, nb_entry);
  15.442 -      break;
  15.443 -    }
  15.444 -  }
  15.445 -
  15.446 -  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xi->tx_ring, notify);
  15.447 -  if (notify) {
  15.448 -    XnNotify(xi->handle, xi->event_channel);
  15.449 -  }
  15.450 -  //FUNCTION_EXIT();
  15.451 -}
  15.452 -
  15.453 -// Called at DISPATCH_LEVEL
  15.454 -VOID
  15.455 -XenNet_TxBufferGC(struct xennet_info *xi, BOOLEAN dont_set_event)
  15.456 -{
  15.457 -  RING_IDX cons, prod;
  15.458 -  PNET_BUFFER_LIST nbl_head = NULL;
  15.459 -  PNET_BUFFER_LIST nbl_tail = NULL;  
  15.460 -  PNET_BUFFER_LIST nbl;
  15.461 -  PNET_BUFFER nb;
  15.462 -  ULONG tx_packets = 0;
  15.463 -
  15.464 -  //FUNCTION_ENTER();
  15.465 -
  15.466 -  NT_ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
  15.467 -
  15.468 -  KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
  15.469 -
  15.470 -//  InitializeListHead(&nbl_head);
  15.471 -  if (xi->device_state != DEVICE_STATE_ACTIVE && !xi->tx_outstanding) {
  15.472 -    /* there is a chance that our Dpc had been queued just before the shutdown... */
  15.473 -    KeSetEvent(&xi->tx_idle_event, IO_NO_INCREMENT, FALSE);
  15.474 -    KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
  15.475 -    return;
  15.476 -  }
  15.477 -
  15.478 -  do {
  15.479 -    prod = xi->tx_ring.sring->rsp_prod;
  15.480 -    KeMemoryBarrier(); /* Ensure we see responses up to 'rsp_prod'. */
  15.481 -
  15.482 -    for (cons = xi->tx_ring.rsp_cons; cons != prod; cons++)
  15.483 -    {
  15.484 -      struct netif_tx_response *txrsp;
  15.485 -      tx_shadow_t *shadow;
  15.486 -      
  15.487 -      txrsp = RING_GET_RESPONSE(&xi->tx_ring, cons);
  15.488 -      
  15.489 -      xi->tx_ring_free++;
  15.490 -