win-pvdrivers

changeset 942:81f132396f9e

xennet6 now appears to pass all significat whql tests. Need to turn down the noise a bit now.
author James Harper <james.harper@bendigoit.com.au>
date Sat Jul 09 18:40:28 2011 +1000 (2011-07-09)
parents 82f5e39717b3
children e16e389a3cb5
files xennet/xennet.inx xennet/xennet6.c xennet/xennet6.h xennet/xennet6_common.c xennet/xennet6_oid.c xennet/xennet6_rx.c xennet/xennet6_tx.c
line diff
     1.1 --- a/xennet/xennet.inx	Sun Jul 03 10:28:34 2011 +1000
     1.2 +++ b/xennet/xennet.inx	Sat Jul 09 18:40:28 2011 +1000
     1.3 @@ -29,7 +29,7 @@ Characteristics = 0x81 ; NCF_VIRTUAL | N
     1.4  AddReg = XenNet_Reg, XenNet_Params_Common, XenNet_Params_NDIS5
     1.5  *IfType            = 6  ; Ethernet
     1.6  *MediaType         = 0	; NdisMedium802_3
     1.7 -*PhysicalMediaType = 19	; NdisPhysicalMedium802_3 
     1.8 +*PhysicalMediaType = 19	; NdisPhysicalMediumOther
     1.9  
    1.10  [XenNet_Inst_NDIS6]
    1.11  CopyFiles=XenNet.CopyFiles
    1.12 @@ -37,7 +37,7 @@ Characteristics = 0x81 ; NCF_VIRTUAL | N
    1.13  AddReg = XenNet_Reg, XenNet_Params_Common, XenNet_Params_NDIS6
    1.14  *IfType            = 6  ; Ethernet
    1.15  *MediaType         = 0	; NdisMedium802_3
    1.16 -*PhysicalMediaType = 19	; NdisPhysicalMedium802_3 
    1.17 +*PhysicalMediaType = 19	; NdisPhysicalMediumOther
    1.18  
    1.19  [XenNet_Reg]
    1.20  HKR, Ndi, Service, 0, "XenNet"
     2.1 --- a/xennet/xennet6.c	Sun Jul 03 10:28:34 2011 +1000
     2.2 +++ b/xennet/xennet6.c	Sat Jul 09 18:40:28 2011 +1000
     2.3 @@ -482,6 +482,8 @@ XenNet_D0Entry(struct xennet_info *xi)
     2.4  
     2.5    return status;
     2.6  }
     2.7 +
     2.8 +#if 0
     2.9  static NDIS_OID supported_oids[] =
    2.10  {
    2.11    /* mandatory */
    2.12 @@ -503,6 +505,8 @@ static NDIS_OID supported_oids[] =
    2.13    OID_GEN_LINK_PARAMETERS,       // S
    2.14    OID_GEN_INTERRUPT_MODERATION,  // QS
    2.15    
    2.16 +  OID_GEN_MAXIMUM_SEND_PACKETS,  // Q
    2.17 +
    2.18    /* general optional */
    2.19    OID_GEN_NETWORK_LAYER_ADDRESSES,       
    2.20    OID_GEN_TRANSPORT_HEADER_OFFSET,
    2.21 @@ -534,6 +538,7 @@ static NDIS_OID supported_oids[] =
    2.22    OID_TCP_OFFLOAD_PARAMETERS,
    2.23    OID_OFFLOAD_ENCAPSULATION,
    2.24  };
    2.25 +#endif
    2.26  
    2.27  // Called at <= DISPATCH_LEVEL
    2.28  static NDIS_STATUS
    2.29 @@ -563,6 +568,7 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
    2.30    NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES offload_attributes;
    2.31    NDIS_OFFLOAD df_offload, hw_offload;
    2.32    NDIS_TCP_CONNECTION_OFFLOAD df_conn_offload, hw_conn_offload;
    2.33 +  static NDIS_OID *supported_oids;
    2.34  
    2.35    UNREFERENCED_PARAMETER(driver_context);
    2.36  
    2.37 @@ -587,14 +593,33 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
    2.38    xi->current_lookahead = MIN_LOOKAHEAD_LENGTH;
    2.39  
    2.40    xi->event_channel = 0;
    2.41 -#if 0
    2.42 -  xi->config_csum = 1;
    2.43 -  xi->config_csum_rx_check = 1;
    2.44 -  xi->config_sg = 1;
    2.45 -  xi->config_gso = 61440;
    2.46 -  xi->config_page = NULL;
    2.47 -  xi->config_rx_interrupt_moderation = 0;
    2.48 -#endif
    2.49 +  xi->stats.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
    2.50 +  xi->stats.Header.Revision = NDIS_STATISTICS_INFO_REVISION_1;
    2.51 +  xi->stats.Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1;
    2.52 +  xi->stats.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED
    2.53 +    | NDIS_STATISTICS_RCV_OK_SUPPORTED
    2.54 +    | NDIS_STATISTICS_XMIT_ERROR_SUPPORTED
    2.55 +    | NDIS_STATISTICS_RCV_ERROR_SUPPORTED
    2.56 +    | NDIS_STATISTICS_RCV_NO_BUFFER_SUPPORTED
    2.57 +    | NDIS_STATISTICS_DIRECTED_BYTES_XMIT_SUPPORTED
    2.58 +    | NDIS_STATISTICS_DIRECTED_FRAMES_XMIT_SUPPORTED
    2.59 +    | NDIS_STATISTICS_MULTICAST_BYTES_XMIT_SUPPORTED
    2.60 +    | NDIS_STATISTICS_MULTICAST_FRAMES_XMIT_SUPPORTED
    2.61 +    | NDIS_STATISTICS_BROADCAST_BYTES_XMIT_SUPPORTED
    2.62 +    | NDIS_STATISTICS_BROADCAST_FRAMES_XMIT_SUPPORTED
    2.63 +    | NDIS_STATISTICS_DIRECTED_BYTES_RCV_SUPPORTED
    2.64 +    | NDIS_STATISTICS_DIRECTED_FRAMES_RCV_SUPPORTED
    2.65 +    | NDIS_STATISTICS_MULTICAST_BYTES_RCV_SUPPORTED
    2.66 +    | NDIS_STATISTICS_MULTICAST_FRAMES_RCV_SUPPORTED
    2.67 +    | NDIS_STATISTICS_BROADCAST_BYTES_RCV_SUPPORTED
    2.68 +    | NDIS_STATISTICS_BROADCAST_FRAMES_RCV_SUPPORTED
    2.69 +    | NDIS_STATISTICS_RCV_CRC_ERROR_SUPPORTED
    2.70 +    | NDIS_STATISTICS_TRANSMIT_QUEUE_LENGTH_SUPPORTED
    2.71 +    | NDIS_STATISTICS_BYTES_RCV_SUPPORTED
    2.72 +    | NDIS_STATISTICS_BYTES_XMIT_SUPPORTED
    2.73 +    | NDIS_STATISTICS_RCV_DISCARDS_SUPPORTED
    2.74 +    | NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED
    2.75 +    | NDIS_STATISTICS_XMIT_DISCARDS_SUPPORTED;
    2.76    
    2.77    nrl = init_parameters->AllocatedResources;
    2.78    for (i = 0; i < nrl->Count; i++)
    2.79 @@ -861,35 +886,27 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
    2.80    general_attributes.ConnectionType = NET_IF_CONNECTION_DEDICATED;
    2.81    general_attributes.IfType = IF_TYPE_ETHERNET_CSMACD;
    2.82    general_attributes.IfConnectorPresent = TRUE;
    2.83 -  general_attributes.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED              
    2.84 -    | NDIS_STATISTICS_RCV_OK_SUPPORTED               
    2.85 -    | NDIS_STATISTICS_XMIT_ERROR_SUPPORTED           
    2.86 -    | NDIS_STATISTICS_RCV_ERROR_SUPPORTED            
    2.87 -    | NDIS_STATISTICS_RCV_NO_BUFFER_SUPPORTED        
    2.88 -    | NDIS_STATISTICS_DIRECTED_BYTES_XMIT_SUPPORTED  
    2.89 -    | NDIS_STATISTICS_DIRECTED_FRAMES_XMIT_SUPPORTED 
    2.90 -    | NDIS_STATISTICS_MULTICAST_BYTES_XMIT_SUPPORTED 
    2.91 -    | NDIS_STATISTICS_MULTICAST_FRAMES_XMIT_SUPPORTED
    2.92 -    | NDIS_STATISTICS_BROADCAST_BYTES_XMIT_SUPPORTED 
    2.93 -    | NDIS_STATISTICS_BROADCAST_FRAMES_XMIT_SUPPORTED
    2.94 -    | NDIS_STATISTICS_DIRECTED_BYTES_RCV_SUPPORTED   
    2.95 -    | NDIS_STATISTICS_DIRECTED_FRAMES_RCV_SUPPORTED  
    2.96 -    | NDIS_STATISTICS_MULTICAST_BYTES_RCV_SUPPORTED  
    2.97 -    | NDIS_STATISTICS_MULTICAST_FRAMES_RCV_SUPPORTED 
    2.98 -    | NDIS_STATISTICS_BROADCAST_BYTES_RCV_SUPPORTED  
    2.99 -    | NDIS_STATISTICS_BROADCAST_FRAMES_RCV_SUPPORTED 
   2.100 -    | NDIS_STATISTICS_RCV_CRC_ERROR_SUPPORTED        
   2.101 -    | NDIS_STATISTICS_TRANSMIT_QUEUE_LENGTH_SUPPORTED
   2.102 -    | NDIS_STATISTICS_BYTES_RCV_SUPPORTED            
   2.103 -    | NDIS_STATISTICS_BYTES_XMIT_SUPPORTED           
   2.104 -    | NDIS_STATISTICS_RCV_DISCARDS_SUPPORTED         
   2.105 -    | NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED       
   2.106 -    | NDIS_STATISTICS_XMIT_DISCARDS_SUPPORTED;
   2.107 +  general_attributes.SupportedStatistics = xi->stats.SupportedStatistics;
   2.108    general_attributes.SupportedPauseFunctions = NdisPauseFunctionsUnsupported;
   2.109    general_attributes.DataBackFillSize = 0; // see NdisRetreatNetBufferDataStart
   2.110    general_attributes.ContextBackFillSize = 0; // ?? NFI ??
   2.111 +  
   2.112 +  for (i = 0; xennet_oids[i].oid; i++);
   2.113 +  
   2.114 +  status = NdisAllocateMemoryWithTag((PVOID)&supported_oids, sizeof(NDIS_OID) * i, XENNET_POOL_TAG);
   2.115 +  if (!NT_SUCCESS(status))
   2.116 +  {
   2.117 +    KdPrint(("NdisAllocateMemoryWithTag failed with 0x%x\n", status));
   2.118 +    status = NDIS_STATUS_RESOURCES;
   2.119 +    goto err;
   2.120 +  }
   2.121 +
   2.122 +  for (i = 0; xennet_oids[i].oid; i++)
   2.123 +  {
   2.124 +    supported_oids[i] = xennet_oids[i].oid;
   2.125 +  }
   2.126    general_attributes.SupportedOidList = supported_oids;
   2.127 -  general_attributes.SupportedOidListLength = sizeof(supported_oids);
   2.128 +  general_attributes.SupportedOidListLength = sizeof(NDIS_OID) * i;
   2.129    general_attributes.AutoNegotiationFlags = NDIS_LINK_STATE_XMIT_LINK_SPEED_AUTO_NEGOTIATED
   2.130      | NDIS_LINK_STATE_RCV_LINK_SPEED_AUTO_NEGOTIATED
   2.131      | NDIS_LINK_STATE_DUPLEX_AUTO_NEGOTIATED;
   2.132 @@ -900,7 +917,8 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   2.133      KdPrint(("NdisMSetMiniportAttributes(general) failed (%08x)\n", status));
   2.134      goto err;
   2.135    }
   2.136 -  
   2.137 +  NdisFreeMemory(supported_oids, 0, 0);
   2.138 +    
   2.139    /* this is the initial offload state */
   2.140    RtlZeroMemory(&df_offload, sizeof(df_offload));
   2.141    df_offload.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
     3.1 --- a/xennet/xennet6.h	Sun Jul 03 10:28:34 2011 +1000
     3.2 +++ b/xennet/xennet6.h	Sat Jul 09 18:40:28 2011 +1000
     3.3 @@ -34,13 +34,13 @@ Foundation, Inc., 51 Franklin Street, Fi
     3.4  #define VENDOR_DRIVER_VERSION_MAJOR 0
     3.5  #define VENDOR_DRIVER_VERSION_MINOR 10
     3.6  
     3.7 -#define MAX_LINK_SPEED 10000000; /* there is not really any theoretical maximum... */
     3.8 +#define MAX_LINK_SPEED 10000000000L; /* there is not really any theoretical maximum... */
     3.9  
    3.10  #define VENDOR_DRIVER_VERSION (((VENDOR_DRIVER_VERSION_MAJOR) << 16) | (VENDOR_DRIVER_VERSION_MINOR))
    3.11  
    3.12  #define __DRIVER_NAME "XenNet"
    3.13  
    3.14 -#define NB_LIST_ENTRY_FIELD MiniportReserved[0] // TX
    3.15 +#define NB_LIST_ENTRY_FIELD MiniportReserved[0] // TX (2 entries)
    3.16  #define NB_HEADER_BUF_FIELD MiniportReserved[0] // RX
    3.17  #define NB_NBL_FIELD MiniportReserved[2] // TX
    3.18  #define NB_LIST_ENTRY(_nb) (*(PLIST_ENTRY)&(_nb)->NB_LIST_ENTRY_FIELD)
    3.19 @@ -48,9 +48,11 @@ Foundation, Inc., 51 Franklin Street, Fi
    3.20  #define NB_HEADER_BUF(_nb) (*(shared_buffer_t **)&(_nb)->NB_HEADER_BUF_FIELD)
    3.21  
    3.22  #define NBL_REF_FIELD MiniportReserved[0] // TX
    3.23 +//#define NBL_LIST_ENTRY_FIELD MiniportReserved[0] // TX (2 entries) - overlaps with REF_FIELD
    3.24  //#define NBL_PACKET_COUNT_FIELD MiniportReserved[0] // RX
    3.25  //#define NBL_LAST_NB_FIELD MiniportReserved[1] // RX
    3.26  #define NBL_REF(_nbl) (*(ULONG_PTR *)&(_nbl)->NBL_REF_FIELD)
    3.27 +//#define NBL_LIST_ENTRY(_nbl) (*(PLIST_ENTRY)&(_nbl)->NBL_LIST_ENTRY_FIELD)
    3.28  //#define NBL_PACKET_COUNT(_nbl) (*(ULONG_PTR *)&(_nbl)->NBL_PACKET_COUNT_FIELD)
    3.29  //#define NBL_LAST_NB(_nbl) (*(PNET_BUFFER *)&(_nbl)->NBL_LAST_NB_FIELD)
    3.30  
    3.31 @@ -185,7 +187,7 @@ SET_NET_ULONG(PVOID ptr, ULONG data)
    3.32  #define MAX_PKT_HEADER_LENGTH (MAX_ETH_HEADER_LENGTH + MAX_IP4_HEADER_LENGTH + MAX_TCP_HEADER_LENGTH)
    3.33  
    3.34  #define MIN_LOOKAHEAD_LENGTH (MAX_IP4_HEADER_LENGTH + MAX_TCP_HEADER_LENGTH)
    3.35 -#define MAX_LOOKAHEAD_LENGTH 256
    3.36 +#define MAX_LOOKAHEAD_LENGTH PAGE_SIZE /* don't know if this is a good idea - was 256*/
    3.37  
    3.38  #define LINUX_MAX_SG_ELEMENTS 19
    3.39  
    3.40 @@ -242,6 +244,8 @@ typedef struct {
    3.41    USHORT tcp_length;
    3.42    USHORT tcp_remaining;
    3.43    ULONG tcp_seq;
    3.44 +  BOOLEAN is_multicast;
    3.45 +  BOOLEAN is_broadcast;
    3.46    /* anything past here doesn't get cleared automatically by the ClearPacketInfo */
    3.47    UCHAR header_data[MAX_LOOKAHEAD_LENGTH + MAX_ETH_HEADER_LENGTH];
    3.48  } packet_info_t;
    3.49 @@ -358,15 +362,26 @@ struct xennet_info
    3.50    /* config stuff calculated from the above */
    3.51    ULONG config_max_pkt_size;
    3.52  
    3.53 -  /* stats */
    3.54 -  ULONG64 stat_tx_ok;
    3.55 -  ULONG64 stat_rx_ok;
    3.56 -  ULONG64 stat_tx_error;
    3.57 -  ULONG64 stat_rx_error;
    3.58 -  ULONG64 stat_rx_no_buffer;
    3.59 +  /* stats */\
    3.60 +  NDIS_STATISTICS_INFO stats;
    3.61 +  //ULONG64 stat_tx_ok;
    3.62 +  //ULONG64 stat_rx_ok;
    3.63 +  //ULONG64 stat_tx_error;
    3.64 +  //ULONG64 stat_rx_error;
    3.65 +  //ULONG64 stat_rx_no_buffer;
    3.66    
    3.67  } typedef xennet_info_t;
    3.68  
    3.69 +struct xennet_oids_t {
    3.70 +  ULONG oid;
    3.71 +  char *oid_name;
    3.72 +  ULONG min_length;
    3.73 +  MINIPORT_OID_REQUEST *query_routine;
    3.74 +  MINIPORT_OID_REQUEST *set_routine;
    3.75 +};
    3.76 +
    3.77 +extern struct xennet_oids_t xennet_oids[];
    3.78 +
    3.79  MINIPORT_OID_REQUEST XenNet_OidRequest;
    3.80  MINIPORT_CANCEL_OID_REQUEST XenNet_CancelOidRequest;
    3.81  
     4.1 --- a/xennet/xennet6_common.c	Sun Jul 03 10:28:34 2011 +1000
     4.2 +++ b/xennet/xennet6_common.c	Sat Jul 09 18:40:28 2011 +1000
     4.3 @@ -138,6 +138,17 @@ XenNet_ParsePacketHeader(packet_info_t *
     4.4      return;
     4.5    }
     4.6  
     4.7 +  if (pi->header[0] == 0xFF && pi->header[1] == 0xFF
     4.8 +      && pi->header[2] == 0xFF && pi->header[3] == 0xFF
     4.9 +      && pi->header[4] == 0xFF && pi->header[5] == 0xFF)
    4.10 +  {
    4.11 +    pi->is_broadcast = TRUE;
    4.12 +  }
    4.13 +  else if (pi->header[0] & 0x01)
    4.14 +  {
    4.15 +    pi->is_multicast = TRUE;
    4.16 +  }
    4.17 +
    4.18    switch (GET_NET_PUSHORT(&pi->header[12])) // L2 protocol field
    4.19    {
    4.20    case 0x0800: /* IPv4 */
    4.21 @@ -251,21 +262,16 @@ XenNet_SumIpHeader(
    4.22  BOOLEAN
    4.23  XenNet_FilterAcceptPacket(struct xennet_info *xi,packet_info_t *pi)
    4.24  {
    4.25 -  BOOLEAN is_multicast = FALSE;
    4.26 +  ULONG i;
    4.27    BOOLEAN is_my_multicast = FALSE;
    4.28 -  BOOLEAN is_broadcast = FALSE;
    4.29    BOOLEAN is_directed = FALSE;
    4.30 -  ULONG i;
    4.31  
    4.32 -  if (pi->header[0] == 0xFF && pi->header[1] == 0xFF
    4.33 -      && pi->header[2] == 0xFF && pi->header[3] == 0xFF
    4.34 -      && pi->header[4] == 0xFF && pi->header[5] == 0xFF)
    4.35 +  if (memcmp(xi->curr_mac_addr, pi->header, ETH_ALEN) == 0)
    4.36    {
    4.37 -    is_broadcast = TRUE;
    4.38 +    is_directed = TRUE;
    4.39    }
    4.40 -  else if (pi->header[0] & 0x01)
    4.41 +  else if (pi->is_multicast)
    4.42    {
    4.43 -    is_multicast = TRUE;
    4.44      for (i = 0; i < xi->multicast_list_size; i++)
    4.45      {
    4.46        if (memcmp(xi->multicast_list[i], pi->header, 6) == 0)
    4.47 @@ -274,13 +280,8 @@ XenNet_FilterAcceptPacket(struct xennet_
    4.48      if (i < xi->multicast_list_size)
    4.49      {
    4.50        is_my_multicast = TRUE;
    4.51 -    }    
    4.52 +    }
    4.53    }
    4.54 -  if (memcmp(xi->curr_mac_addr, pi->header, ETH_ALEN) == 0)
    4.55 -  {
    4.56 -    is_directed = TRUE;
    4.57 -  }
    4.58 -
    4.59    if (is_directed && (xi->packet_filter & NDIS_PACKET_TYPE_DIRECTED))
    4.60    {
    4.61      return TRUE;
    4.62 @@ -289,11 +290,11 @@ XenNet_FilterAcceptPacket(struct xennet_
    4.63    {
    4.64      return TRUE;
    4.65    }
    4.66 -  if (is_multicast && (xi->packet_filter & NDIS_PACKET_TYPE_ALL_MULTICAST))
    4.67 +  if (pi->is_multicast && (xi->packet_filter & NDIS_PACKET_TYPE_ALL_MULTICAST))
    4.68    {
    4.69      return TRUE;
    4.70    }
    4.71 -  if (is_broadcast && (xi->packet_filter & NDIS_PACKET_TYPE_BROADCAST))
    4.72 +  if (pi->is_broadcast && (xi->packet_filter & NDIS_PACKET_TYPE_BROADCAST))
    4.73    {
    4.74      return TRUE;
    4.75    }
    4.76 @@ -301,6 +302,6 @@ XenNet_FilterAcceptPacket(struct xennet_
    4.77    {
    4.78      return TRUE;
    4.79    }
    4.80 -  return TRUE;
    4.81 -  //return FALSE;
    4.82 +  //return TRUE;
    4.83 +  return FALSE;
    4.84  }
     5.1 --- a/xennet/xennet6_oid.c	Sun Jul 03 10:28:34 2011 +1000
     5.2 +++ b/xennet/xennet6_oid.c	Sat Jul 09 18:40:28 2011 +1000
     5.3 @@ -20,6 +20,406 @@ Foundation, Inc., 51 Franklin Street, Fi
     5.4  
     5.5  #include "xennet6.h"
     5.6  
     5.7 +#define DEF_OID_QUERY(oid, min_length) {oid, #oid, min_length, XenNet_Query##oid, NULL}
     5.8 +#define DEF_OID_QUERYSET(oid, min_length) {oid, #oid, min_length, XenNet_Query##oid, XenNet_Set##oid}
     5.9 +#define DEF_OID_SET(oid, min_length) {oid, #oid, min_length, NULL, XenNet_Set##oid}
    5.10 +
    5.11 +#define DEF_OID_QUERY_STAT(oid) DEF_OID_QUERY(##oid, 0) /* has to be 0 so the 4/8 size works */
    5.12 +#define DEF_OID_QUERY_ULONG(oid) DEF_OID_QUERY(##oid, sizeof(ULONG))
    5.13 +#define DEF_OID_QUERYSET_ULONG(oid) DEF_OID_QUERYSET(##oid, sizeof(ULONG))
    5.14 +#define DEF_OID_SET_ULONG(oid) DEF_OID_SET(##oid, sizeof(ULONG))
    5.15 +
    5.16 +/*
    5.17 +#define SET_ULONG(value) \
    5.18 +  do { \
    5.19 +    request->DATA.SET_INFORMATION.InformationBufferLength = sizeof(ULONG); \
    5.20 +    *(ULONG *)request->DATA.SET_INFORMATION.InformationBuffer = value; \
    5.21 +  } while (0);
    5.22 +*/
    5.23 +#define DEF_OID_QUERY_ROUTINE(oid, value, length) \
    5.24 +NDIS_STATUS \
    5.25 +XenNet_Query##oid(NDIS_HANDLE context, PNDIS_OID_REQUEST request) \
    5.26 +{ \
    5.27 +  struct xennet_info *xi = context; \
    5.28 +  UNREFERENCED_PARAMETER(xi); \
    5.29 +  if (request->DATA.QUERY_INFORMATION.InformationBufferLength < length) \
    5.30 +  { \
    5.31 +    request->DATA.QUERY_INFORMATION.BytesNeeded = length; \
    5.32 +    return NDIS_STATUS_BUFFER_TOO_SHORT; \
    5.33 +  } \
    5.34 +  request->DATA.QUERY_INFORMATION.BytesWritten = length; \
    5.35 +  NdisMoveMemory(request->DATA.QUERY_INFORMATION.InformationBuffer, value, length); \
    5.36 +  return STATUS_SUCCESS; \
    5.37 +}
    5.38 +
    5.39 +#define DEF_OID_QUERY_ULONG_ROUTINE(oid, value) \
    5.40 +NDIS_STATUS \
    5.41 +XenNet_Query##oid(NDIS_HANDLE context, PNDIS_OID_REQUEST request) \
    5.42 +{ \
    5.43 +  struct xennet_info *xi = context; \
    5.44 +  UNREFERENCED_PARAMETER(xi); \
    5.45 +  request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(ULONG); \
    5.46 +  *(ULONG *)request->DATA.QUERY_INFORMATION.InformationBuffer = value; \
    5.47 +  return STATUS_SUCCESS; \
    5.48 +}
    5.49 +
    5.50 +#define DEF_OID_QUERY_STAT_ROUTINE(oid, value) \
    5.51 +NDIS_STATUS \
    5.52 +XenNet_Query##oid(NDIS_HANDLE context, PNDIS_OID_REQUEST request) \
    5.53 +{ \
    5.54 +  struct xennet_info *xi = context; \
    5.55 +  UNREFERENCED_PARAMETER(xi); \
    5.56 +  if (request->DATA.QUERY_INFORMATION.InformationBufferLength >= 8) \
    5.57 +  { \
    5.58 +    request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(ULONG64); \
    5.59 +    *(ULONG64 *)request->DATA.QUERY_INFORMATION.InformationBuffer = (value); \
    5.60 +  } \
    5.61 +  else if (request->DATA.QUERY_INFORMATION.InformationBufferLength >= 4) \
    5.62 +  { \
    5.63 +    request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(ULONG); \
    5.64 +    request->DATA.QUERY_INFORMATION.BytesNeeded = sizeof(ULONG64); \
    5.65 +    *(ULONG *)request->DATA.QUERY_INFORMATION.InformationBuffer = (ULONG)(value); \
    5.66 +  } \
    5.67 +  else \
    5.68 +  { \
    5.69 +    request->DATA.QUERY_INFORMATION.BytesNeeded = sizeof(ULONG64); \
    5.70 +    return NDIS_STATUS_BUFFER_TOO_SHORT; \
    5.71 +  } \
    5.72 +  return STATUS_SUCCESS; \
    5.73 +}
    5.74 +
    5.75 +DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_MAXIMUM_TOTAL_SIZE, xi->current_mtu_value + XN_HDR_SIZE)
    5.76 +DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_CURRENT_PACKET_FILTER, xi->packet_filter)
    5.77 +DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_CURRENT_LOOKAHEAD, xi->current_lookahead)
    5.78 +DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_TRANSMIT_BUFFER_SPACE, PAGE_SIZE * NET_TX_RING_SIZE * 4)
    5.79 +DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_RECEIVE_BUFFER_SPACE, PAGE_SIZE * NET_RX_RING_SIZE * 2)
    5.80 +DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_TRANSMIT_BLOCK_SIZE, PAGE_SIZE)
    5.81 +DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_RECEIVE_BLOCK_SIZE, PAGE_SIZE)
    5.82 +DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_MAXIMUM_SEND_PACKETS, 0)
    5.83 +DEF_OID_QUERY_ULONG_ROUTINE(OID_802_3_MAXIMUM_LIST_SIZE, MULTICAST_LIST_MAX_SIZE)
    5.84 +DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_HARDWARE_STATUS, xi->connected?NdisHardwareStatusReady:NdisHardwareStatusInitializing)
    5.85 +DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_VENDOR_ID, 0xFFFFFF) // Not guaranteed to be XENSOURCE_MAC_HDR;
    5.86 +DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_VENDOR_DRIVER_VERSION, VENDOR_DRIVER_VERSION)
    5.87 +DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_MEDIA_SUPPORTED, NdisMedium802_3)
    5.88 +DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_MEDIA_IN_USE, NdisMedium802_3)
    5.89 +DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_MAXIMUM_LOOKAHEAD, MAX_LOOKAHEAD_LENGTH)
    5.90 +
    5.91 +DEF_OID_QUERY_STAT_ROUTINE(OID_GEN_XMIT_OK, xi->stats.ifHCOutUcastPkts + xi->stats.ifHCOutMulticastPkts + xi->stats.ifHCOutBroadcastPkts)
    5.92 +DEF_OID_QUERY_STAT_ROUTINE(OID_GEN_XMIT_ERROR, xi->stats.ifOutErrors)
    5.93 +DEF_OID_QUERY_STAT_ROUTINE(OID_GEN_RCV_OK, xi->stats.ifHCInUcastPkts + xi->stats.ifHCInMulticastPkts + xi->stats.ifHCInBroadcastPkts)
    5.94 +DEF_OID_QUERY_STAT_ROUTINE(OID_GEN_RCV_ERROR, xi->stats.ifInErrors)
    5.95 +DEF_OID_QUERY_STAT_ROUTINE(OID_GEN_RCV_NO_BUFFER, xi->stats.ifInDiscards)
    5.96 +DEF_OID_QUERY_STAT_ROUTINE(OID_802_3_RCV_ERROR_ALIGNMENT, 0)
    5.97 +DEF_OID_QUERY_STAT_ROUTINE(OID_802_3_XMIT_ONE_COLLISION, 0)
    5.98 +DEF_OID_QUERY_STAT_ROUTINE(OID_802_3_XMIT_MORE_COLLISIONS, 0)
    5.99 +
   5.100 +DEF_OID_QUERY_ROUTINE(OID_GEN_VENDOR_DESCRIPTION, XN_VENDOR_DESC, sizeof(XN_VENDOR_DESC))
   5.101 +
   5.102 +DEF_OID_QUERY_ROUTINE(OID_802_3_PERMANENT_ADDRESS, xi->perm_mac_addr, ETH_ALEN)
   5.103 +DEF_OID_QUERY_ROUTINE(OID_802_3_CURRENT_ADDRESS, xi->curr_mac_addr, ETH_ALEN)
   5.104 +
   5.105 +DEF_OID_QUERY_ROUTINE(OID_802_3_MULTICAST_LIST, xi->multicast_list, xi->multicast_list_size * 6)
   5.106 +
   5.107 +NDIS_STATUS
   5.108 +XenNet_SetOID_802_3_MULTICAST_LIST(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
   5.109 +{
   5.110 +  struct xennet_info *xi = context;
   5.111 +  UCHAR *multicast_list;
   5.112 +  int i;
   5.113 +
   5.114 +  if (request->DATA.SET_INFORMATION.InformationBufferLength > MULTICAST_LIST_MAX_SIZE * 6)
   5.115 +  {
   5.116 +    return NDIS_STATUS_MULTICAST_FULL;
   5.117 +  }
   5.118 +  
   5.119 +  if (request->DATA.SET_INFORMATION.InformationBufferLength % 6 != 0)
   5.120 +  {
   5.121 +    return NDIS_STATUS_MULTICAST_FULL;
   5.122 +  }
   5.123 +  multicast_list = request->DATA.SET_INFORMATION.InformationBuffer;
   5.124 +  for (i = 0; i < (int)request->DATA.SET_INFORMATION.InformationBufferLength / 6; i++)
   5.125 +  {
   5.126 +    if (!(multicast_list[i * 6 + 0] & 0x01))
   5.127 +    {
   5.128 +      FUNCTION_MSG("Address %d (%02x:%02x:%02x:%02x:%02x:%02x) is not a multicast address\n", i,
   5.129 +        (ULONG)multicast_list[i * 6 + 0], (ULONG)multicast_list[i * 6 + 1], 
   5.130 +        (ULONG)multicast_list[i * 6 + 2], (ULONG)multicast_list[i * 6 + 3], 
   5.131 +        (ULONG)multicast_list[i * 6 + 4], (ULONG)multicast_list[i * 6 + 5]);
   5.132 +      /* 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... */
   5.133 +    }
   5.134 +  }
   5.135 +  memcpy(xi->multicast_list, multicast_list, request->DATA.SET_INFORMATION.InformationBufferLength);
   5.136 +  xi->multicast_list_size = request->DATA.SET_INFORMATION.InformationBufferLength / 6;
   5.137 +  return NDIS_STATUS_SUCCESS;
   5.138 +}
   5.139 +
   5.140 +NDIS_STATUS
   5.141 +XenNet_SetOID_GEN_CURRENT_PACKET_FILTER(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
   5.142 +{
   5.143 +  struct xennet_info *xi = context;
   5.144 +  PULONG data = request->DATA.SET_INFORMATION.InformationBuffer;
   5.145 +  
   5.146 +  request->DATA.SET_INFORMATION.BytesNeeded = sizeof(ULONG64);
   5.147 +  if (*data & NDIS_PACKET_TYPE_DIRECTED)
   5.148 +    FUNCTION_MSG("NDIS_PACKET_TYPE_DIRECTED\n");
   5.149 +  if (*data & NDIS_PACKET_TYPE_MULTICAST)
   5.150 +    FUNCTION_MSG("NDIS_PACKET_TYPE_MULTICAST\n");
   5.151 +  if (*data & NDIS_PACKET_TYPE_ALL_MULTICAST)
   5.152 +    FUNCTION_MSG("NDIS_PACKET_TYPE_ALL_MULTICAST\n");
   5.153 +  if (*data & NDIS_PACKET_TYPE_BROADCAST)
   5.154 +    FUNCTION_MSG("NDIS_PACKET_TYPE_BROADCAST\n");
   5.155 +  if (*data & NDIS_PACKET_TYPE_PROMISCUOUS)
   5.156 +    FUNCTION_MSG("NDIS_PACKET_TYPE_PROMISCUOUS\n");
   5.157 +  if (*data & NDIS_PACKET_TYPE_ALL_FUNCTIONAL)
   5.158 +    FUNCTION_MSG("NDIS_PACKET_TYPE_ALL_FUNCTIONAL (not supported)\n");
   5.159 +  if (*data & NDIS_PACKET_TYPE_ALL_LOCAL)
   5.160 +    FUNCTION_MSG("NDIS_PACKET_TYPE_ALL_LOCAL (not supported)\n");
   5.161 +  if (*data & NDIS_PACKET_TYPE_FUNCTIONAL)
   5.162 +    FUNCTION_MSG("NDIS_PACKET_TYPE_FUNCTIONAL (not supported)\n");
   5.163 +  if (*data & NDIS_PACKET_TYPE_GROUP)
   5.164 +    FUNCTION_MSG("NDIS_PACKET_TYPE_GROUP (not supported)\n");
   5.165 +  if (*data & ~SUPPORTED_PACKET_FILTERS)
   5.166 +  {
   5.167 +    FUNCTION_MSG("returning NDIS_STATUS_NOT_SUPPORTED\n");
   5.168 +    return NDIS_STATUS_NOT_SUPPORTED;
   5.169 +  }
   5.170 +  xi->packet_filter = *(ULONG *)data;
   5.171 +  request->DATA.SET_INFORMATION.BytesRead = sizeof(ULONG);
   5.172 +  return NDIS_STATUS_SUCCESS;
   5.173 +}
   5.174 +
   5.175 +NDIS_STATUS
   5.176 +XenNet_SetOID_GEN_CURRENT_LOOKAHEAD(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
   5.177 +{
   5.178 +  struct xennet_info *xi = context;
   5.179 +  PULONG data = request->DATA.QUERY_INFORMATION.InformationBuffer;
   5.180 +  xi->current_lookahead = *(ULONG *)data;
   5.181 +  FUNCTION_MSG("Set OID_GEN_CURRENT_LOOKAHEAD %d (%p)\n", xi->current_lookahead, xi);
   5.182 +  return NDIS_STATUS_SUCCESS;
   5.183 +}
   5.184 +
   5.185 +NDIS_STATUS
   5.186 +XenNet_SetOID_GEN_LINK_PARAMETERS(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
   5.187 +{
   5.188 +  UNREFERENCED_PARAMETER(context);
   5.189 +  UNREFERENCED_PARAMETER(request);
   5.190 +  return STATUS_NOT_SUPPORTED;
   5.191 +}
   5.192 +
   5.193 +NDIS_STATUS
   5.194 +XenNet_QueryOID_GEN_INTERRUPT_MODERATION(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
   5.195 +{
   5.196 +  PNDIS_INTERRUPT_MODERATION_PARAMETERS nimp;
   5.197 +  UNREFERENCED_PARAMETER(context);
   5.198 +  nimp = (PNDIS_INTERRUPT_MODERATION_PARAMETERS)request->DATA.QUERY_INFORMATION.InformationBuffer;
   5.199 +  nimp->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
   5.200 +  nimp->Header.Revision = NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
   5.201 +  nimp->Header.Size = NDIS_SIZEOF_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
   5.202 +  nimp->Flags = 0;
   5.203 +  nimp->InterruptModeration = NdisInterruptModerationNotSupported;
   5.204 +  request->DATA.SET_INFORMATION.BytesRead = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS);
   5.205 +  return STATUS_SUCCESS;
   5.206 +}
   5.207 +
   5.208 +NDIS_STATUS
   5.209 +XenNet_SetOID_GEN_INTERRUPT_MODERATION(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
   5.210 +{
   5.211 +  UNREFERENCED_PARAMETER(context);
   5.212 +  UNREFERENCED_PARAMETER(request);
   5.213 +  return STATUS_NOT_SUPPORTED;
   5.214 +}
   5.215 +
   5.216 +NDIS_STATUS
   5.217 +XenNet_QueryOID_GEN_STATISTICS(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
   5.218 +{
   5.219 +  struct xennet_info *xi = context;
   5.220 +
   5.221 +  NdisMoveMemory(request->DATA.QUERY_INFORMATION.InformationBuffer, &xi->stats, sizeof(NDIS_STATISTICS_INFO));
   5.222 +  request->DATA.SET_INFORMATION.BytesRead = sizeof(NDIS_STATISTICS_INFO);
   5.223 +  return STATUS_SUCCESS;
   5.224 +}
   5.225 +
   5.226 +NDIS_STATUS
   5.227 +XenNet_SetOID_PNP_SET_POWER(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
   5.228 +{
   5.229 +  UNREFERENCED_PARAMETER(context);
   5.230 +  UNREFERENCED_PARAMETER(request);
   5.231 +  return STATUS_NOT_SUPPORTED;
   5.232 +}
   5.233 +
   5.234 +NDIS_STATUS
   5.235 +XenNet_SetOID_GEN_NETWORK_LAYER_ADDRESSES(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
   5.236 +{
   5.237 +  PNETWORK_ADDRESS_LIST nal = request->DATA.QUERY_INFORMATION.InformationBuffer;
   5.238 +  PNETWORK_ADDRESS na;
   5.239 +  PNETWORK_ADDRESS_IP ip;
   5.240 +  int i;
   5.241 +  
   5.242 +  UNREFERENCED_PARAMETER(context);
   5.243 +  FUNCTION_MSG("AddressType = %d\n", nal->AddressType);
   5.244 +  FUNCTION_MSG("AddressCount = %d\n", nal->AddressCount);
   5.245 +  if (nal->AddressCount == 0)
   5.246 +  {
   5.247 +    // remove addresses of AddressType type
   5.248 +  }
   5.249 +  else
   5.250 +  {
   5.251 +    na = nal->Address;
   5.252 +    for (i = 0; i < nal->AddressCount; i++)
   5.253 +    {
   5.254 +      if ((ULONG_PTR)na - (ULONG_PTR)nal + FIELD_OFFSET(NETWORK_ADDRESS, Address) + na->AddressLength > request->DATA.QUERY_INFORMATION.InformationBufferLength)
   5.255 +      {
   5.256 +        FUNCTION_MSG("Out of bounds\n");
   5.257 +        return NDIS_STATUS_INVALID_DATA;
   5.258 +      }
   5.259 +      switch(na->AddressType)
   5.260 +      {
   5.261 +      case NDIS_PROTOCOL_ID_TCP_IP:
   5.262 +        FUNCTION_MSG("Address[%d].Type = NDIS_PROTOCOL_ID_TCP_IP\n", i);
   5.263 +        FUNCTION_MSG("Address[%d].Length = %d\n", i, na->AddressLength);
   5.264 +        if (na->AddressLength != NETWORK_ADDRESS_LENGTH_IP)
   5.265 +        {
   5.266 +          FUNCTION_MSG("Length is invalid\n");
   5.267 +          break;
   5.268 +        }
   5.269 +        ip = (PNETWORK_ADDRESS_IP)na->Address;
   5.270 +        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);
   5.271 +        break;
   5.272 +      default:
   5.273 +        FUNCTION_MSG("Address[%d].Type = %d\n", i, na->AddressType);
   5.274 +        FUNCTION_MSG("Address[%d].Length = %d\n", i, na->AddressLength);
   5.275 +        break;
   5.276 +      }
   5.277 +      na = (PNETWORK_ADDRESS)((PUCHAR)na + FIELD_OFFSET(NETWORK_ADDRESS, Address) + na->AddressLength);
   5.278 +    }
   5.279 +  }
   5.280 +  
   5.281 +  return NDIS_STATUS_SUCCESS;
   5.282 +}
   5.283 +
   5.284 +NDIS_STATUS
   5.285 +XenNet_SetOID_GEN_MACHINE_NAME(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
   5.286 +{
   5.287 +  UNICODE_STRING name;
   5.288 +  UNREFERENCED_PARAMETER(context);
   5.289 +  
   5.290 +  name.Length = (USHORT)request->DATA.QUERY_INFORMATION.InformationBufferLength;
   5.291 +  name.MaximumLength = (USHORT)request->DATA.QUERY_INFORMATION.InformationBufferLength;
   5.292 +  name.Buffer = request->DATA.QUERY_INFORMATION.InformationBuffer;
   5.293 +  FUNCTION_MSG("name = %wZ\n", &name);
   5.294 +  return NDIS_STATUS_SUCCESS;
   5.295 +}
   5.296 +
   5.297 +NDIS_STATUS
   5.298 +XenNet_SetOID_OFFLOAD_ENCAPSULATION(NDIS_HANDLE context, PNDIS_OID_REQUEST request)
   5.299 +{
   5.300 +  struct xennet_info *xi = context;
   5.301 +  /* mostly assume that NDIS vets the settings for us */
   5.302 +  PNDIS_OFFLOAD_ENCAPSULATION noe = (PNDIS_OFFLOAD_ENCAPSULATION)request->DATA.SET_INFORMATION.InformationBuffer;
   5.303 +  if (noe->IPv4.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3)
   5.304 +  {
   5.305 +    FUNCTION_MSG("Unknown Encapsulation Type %d\n", noe->IPv4.EncapsulationType);
   5.306 +    return NDIS_STATUS_NOT_SUPPORTED;
   5.307 +  }
   5.308 +    
   5.309 +  switch(noe->IPv4.Enabled)
   5.310 +  {
   5.311 +  case NDIS_OFFLOAD_SET_ON:
   5.312 +    FUNCTION_MSG(" IPv4.Enabled = NDIS_OFFLOAD_SET_ON\n");
   5.313 +    xi->current_csum_supported = xi->backend_csum_supported && xi->frontend_csum_supported;
   5.314 +    xi->current_gso_value = min(xi->backend_csum_supported, xi->frontend_csum_supported);
   5.315 +    break;
   5.316 +  case NDIS_OFFLOAD_SET_OFF:
   5.317 +    FUNCTION_MSG(" IPv4.Enabled = NDIS_OFFLOAD_SET_OFF\n");
   5.318 +    xi->current_csum_supported = FALSE;
   5.319 +    xi->current_gso_value = 0;
   5.320 +    break;
   5.321 +  case NDIS_OFFLOAD_SET_NO_CHANGE:
   5.322 +    FUNCTION_MSG(" IPv4.Enabled = NDIS_OFFLOAD_NO_CHANGE\n");
   5.323 +    break;
   5.324 +  }
   5.325 +  FUNCTION_MSG(" IPv4.HeaderSize = %d\n", noe->IPv4.HeaderSize);
   5.326 +  FUNCTION_MSG(" IPv6.EncapsulationType = %d\n", noe->IPv6.EncapsulationType);
   5.327 +  switch(noe->IPv6.Enabled)
   5.328 +  {
   5.329 +  case NDIS_OFFLOAD_SET_ON:
   5.330 +    FUNCTION_MSG(" IPv6.Enabled = NDIS_OFFLOAD_SET_ON (this is an error)\n");
   5.331 +    break;
   5.332 +  case NDIS_OFFLOAD_SET_OFF:
   5.333 +    FUNCTION_MSG(" IPv6.Enabled = NDIS_OFFLOAD_SET_OFF\n");
   5.334 +    break;
   5.335 +  case NDIS_OFFLOAD_SET_NO_CHANGE:
   5.336 +    FUNCTION_MSG(" IPv6.Enabled = NDIS_OFFLOAD_NO_CHANGE\n");
   5.337 +    break;
   5.338 +  }
   5.339 +  FUNCTION_MSG(" IPv6.HeaderSize = %d\n", noe->IPv6.HeaderSize);
   5.340 +  return NDIS_STATUS_SUCCESS;
   5.341 +}
   5.342 +
   5.343 +struct xennet_oids_t xennet_oids[] = {
   5.344 +  DEF_OID_QUERY_ULONG(OID_GEN_HARDWARE_STATUS),
   5.345 +
   5.346 +  DEF_OID_QUERY_ULONG(OID_GEN_TRANSMIT_BUFFER_SPACE),
   5.347 +  DEF_OID_QUERY_ULONG(OID_GEN_RECEIVE_BUFFER_SPACE),
   5.348 +  DEF_OID_QUERY_ULONG(OID_GEN_TRANSMIT_BLOCK_SIZE),
   5.349 +  DEF_OID_QUERY_ULONG(OID_GEN_RECEIVE_BLOCK_SIZE),
   5.350 +
   5.351 +  DEF_OID_QUERY_ULONG(OID_GEN_VENDOR_ID),
   5.352 +  DEF_OID_QUERY(OID_GEN_VENDOR_DESCRIPTION, sizeof(XN_VENDOR_DESC)),
   5.353 +  DEF_OID_QUERY_ULONG(OID_GEN_VENDOR_DRIVER_VERSION),
   5.354 +
   5.355 +  DEF_OID_QUERYSET_ULONG(OID_GEN_CURRENT_PACKET_FILTER),
   5.356 +  DEF_OID_QUERYSET_ULONG(OID_GEN_CURRENT_LOOKAHEAD),
   5.357 +  //DEF_OID_QUERY(OID_GEN_DRIVER_VERSION),
   5.358 +  DEF_OID_QUERY_ULONG(OID_GEN_MAXIMUM_TOTAL_SIZE),
   5.359 +  DEF_OID_SET(OID_GEN_LINK_PARAMETERS, sizeof(NDIS_LINK_PARAMETERS)),
   5.360 +  DEF_OID_QUERYSET(OID_GEN_INTERRUPT_MODERATION, sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS)),
   5.361 +  
   5.362 +  DEF_OID_QUERY_ULONG(OID_GEN_MAXIMUM_SEND_PACKETS),
   5.363 +
   5.364 +  /* general optional */
   5.365 +  DEF_OID_SET(OID_GEN_NETWORK_LAYER_ADDRESSES, FIELD_OFFSET(NETWORK_ADDRESS_LIST, Address)),
   5.366 +  DEF_OID_SET(OID_GEN_MACHINE_NAME, 0),
   5.367 +  DEF_OID_SET(OID_OFFLOAD_ENCAPSULATION, sizeof(NDIS_OFFLOAD_ENCAPSULATION)),
   5.368 +  //DEF_OID_QUERY(OID_GEN_TRANSPORT_HEADER_OFFSET, sizeof(TRANSPORT_HEADER_OFFSET)),
   5.369 +
   5.370 +  /* power */
   5.371 +  //DEF_OID_QUERY(OID_PNP_CAPABILITIES, sizeof(NDIS_PNP_CAPABILITIES)),
   5.372 +  DEF_OID_SET_ULONG(OID_PNP_SET_POWER),
   5.373 +  //DEF_OID_QUERY_ULONG(OID_PNP_QUERY_POWER),
   5.374 +  
   5.375 +  /* stats */
   5.376 +  DEF_OID_QUERY_STAT(OID_GEN_XMIT_OK),
   5.377 +  DEF_OID_QUERY_STAT(OID_GEN_RCV_OK),
   5.378 +  DEF_OID_QUERY_STAT(OID_GEN_XMIT_ERROR),
   5.379 +  DEF_OID_QUERY_STAT(OID_GEN_RCV_ERROR),
   5.380 +  DEF_OID_QUERY_STAT(OID_GEN_RCV_NO_BUFFER),
   5.381 +  DEF_OID_QUERY_STAT(OID_802_3_RCV_ERROR_ALIGNMENT),
   5.382 +  DEF_OID_QUERY_STAT(OID_802_3_XMIT_ONE_COLLISION),
   5.383 +  DEF_OID_QUERY_STAT(OID_802_3_XMIT_MORE_COLLISIONS),
   5.384 +  DEF_OID_QUERY_ULONG(OID_GEN_MEDIA_SUPPORTED),
   5.385 +  DEF_OID_QUERY_ULONG(OID_GEN_MEDIA_IN_USE),
   5.386 +  DEF_OID_QUERY(OID_GEN_STATISTICS, sizeof(NDIS_STATISTICS_INFO)),
   5.387 +  DEF_OID_QUERY_ULONG(OID_GEN_MAXIMUM_LOOKAHEAD),
   5.388 +  /* media-specific */
   5.389 +  DEF_OID_QUERY(OID_802_3_PERMANENT_ADDRESS, 6),
   5.390 +  DEF_OID_QUERY(OID_802_3_CURRENT_ADDRESS, 6),
   5.391 +  DEF_OID_QUERYSET(OID_802_3_MULTICAST_LIST, 0),
   5.392 +  DEF_OID_QUERY_ULONG(OID_802_3_MAXIMUM_LIST_SIZE),
   5.393 +  
   5.394 +#if 0
   5.395 +  /* tcp offload */
   5.396 +  DEF_OID_QUERY(OID_TCP_TASK_OFFLOAD,
   5.397 +  DEF_OID_QUERY(OID_TCP_OFFLOAD_PARAMETERS,
   5.398 +  DEF_OID_QUERY(OID_OFFLOAD_ENCAPSULATION,
   5.399 +#endif
   5.400 +
   5.401 +  {0, "", 0, NULL, NULL}
   5.402 +};
   5.403 +
   5.404 +static NDIS_OID supported_oids[ARRAY_SIZE(xennet_oids)];
   5.405 +
   5.406 +#if 0
   5.407  /* return 4 or 8 depending on size of buffer */
   5.408  #define HANDLE_STAT_RETURN \
   5.409    {if (InformationBufferLength == 4) { \
   5.410 @@ -28,8 +428,8 @@ Foundation, Inc., 51 Franklin Street, Fi
   5.411      len = 8; \
   5.412      } }
   5.413  
   5.414 -#define SET_LEN_AND_BREAK_IF_SHORT(_len) do { len = _len; if (len > InformationBufferLength) break; } while(0)
   5.415 -  
   5.416 +#define SET_LEN_AND_BREAK_IF_SHORT(_len) if ((len = _len) > InformationBufferLength) break;
   5.417 +
   5.418  static NDIS_STATUS
   5.419  XenNet_QueryInformation(
   5.420    IN NDIS_HANDLE MiniportAdapterContext,
   5.421 @@ -46,8 +446,8 @@ XenNet_QueryInformation(
   5.422    ULONG64 temp_data;
   5.423    PVOID data = &temp_data;
   5.424    PNDIS_INTERRUPT_MODERATION_PARAMETERS nimp;
   5.425 +  UCHAR vendor_desc[] = XN_VENDOR_DESC;
   5.426  #if 0
   5.427 -  UCHAR vendor_desc[] = XN_VENDOR_DESC;
   5.428    PNDIS_TASK_OFFLOAD_HEADER ntoh;
   5.429    PNDIS_TASK_OFFLOAD nto;
   5.430    PNDIS_TASK_TCP_IP_CHECKSUM nttic;
   5.431 @@ -67,18 +467,6 @@ XenNet_QueryInformation(
   5.432        data = supported_oids;
   5.433        len = sizeof(supported_oids);
   5.434        break;
   5.435 -    case OID_GEN_HARDWARE_STATUS:
   5.436 -      if (!xi->connected)
   5.437 -      {
   5.438 -        temp_data = NdisHardwareStatusInitializing;
   5.439 -        FUNCTION_MSG("NdisHardwareStatusInitializing\n");
   5.440 -      }
   5.441 -      else
   5.442 -      {
   5.443 -        temp_data = NdisHardwareStatusReady;
   5.444 -        FUNCTION_MSG("NdisHardwareStatusReady\n");
   5.445 -      }
   5.446 -      break;
   5.447      case OID_GEN_MEDIA_SUPPORTED:
   5.448        temp_data = NdisMedium802_3;
   5.449        break;
   5.450 @@ -94,31 +482,6 @@ XenNet_QueryInformation(
   5.451      case OID_GEN_LINK_SPEED:
   5.452        temp_data = 10000000; /* 1Gb */
   5.453        break;
   5.454 -    case OID_GEN_TRANSMIT_BUFFER_SPACE:
   5.455 -      /* multiply this by some small number as we can queue additional packets */
   5.456 -      temp_data = PAGE_SIZE * NET_TX_RING_SIZE * 4;
   5.457 -      break;
   5.458 -    case OID_GEN_RECEIVE_BUFFER_SPACE:
   5.459 -      temp_data = PAGE_SIZE * NET_RX_RING_SIZE * 2;
   5.460 -      break;
   5.461 -    case OID_GEN_TRANSMIT_BLOCK_SIZE:
   5.462 -      temp_data = PAGE_SIZE; //XN_MAX_PKT_SIZE;
   5.463 -      break;
   5.464 -    case OID_GEN_RECEIVE_BLOCK_SIZE:
   5.465 -      temp_data = PAGE_SIZE; //XN_MAX_PKT_SIZE;
   5.466 -      break;
   5.467 -    case OID_GEN_VENDOR_DESCRIPTION:
   5.468 -      data = vendor_desc;
   5.469 -      len = sizeof(vendor_desc);
   5.470 -      break;
   5.471 -    case OID_GEN_DRIVER_VERSION:
   5.472 -      temp_data = (NDIS_MINIPORT_MAJOR_VERSION << 8) | NDIS_MINIPORT_MINOR_VERSION;
   5.473 -      len = 2;
   5.474 -      break;
   5.475 -    case OID_GEN_VENDOR_DRIVER_VERSION:
   5.476 -      temp_data = VENDOR_DRIVER_VERSION;
   5.477 -      len = 4;
   5.478 -      break;
   5.479      case OID_GEN_MAC_OPTIONS:
   5.480        temp_data = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | 
   5.481          NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
   5.482 @@ -130,10 +493,6 @@ XenNet_QueryInformation(
   5.483        else
   5.484          temp_data = NdisMediaStateDisconnected;
   5.485        break;
   5.486 -    case OID_GEN_MAXIMUM_SEND_PACKETS:
   5.487 -      /* this is actually ignored for deserialised drivers like us */
   5.488 -      temp_data = 0; //XN_MAX_SEND_PKTS;
   5.489 -      break;
   5.490      case OID_GEN_XMIT_ERROR:
   5.491        temp_data = xi->stat_tx_error;
   5.492        HANDLE_STAT_RETURN;
   5.493 @@ -332,8 +691,21 @@ XenNet_QueryInformation(
   5.494        len = xi->multicast_list_size * 6;
   5.495        break;
   5.496      case OID_GEN_VENDOR_ID:
   5.497 +      FUNCTION_MSG("OID_GEN_VENDOR_ID InformationBufferLength = %d\n", InformationBufferLength);
   5.498        temp_data = 0xFFFFFF; // Not guaranteed to be XENSOURCE_MAC_HDR;
   5.499        break;
   5.500 +    case OID_GEN_VENDOR_DESCRIPTION:
   5.501 +      data = vendor_desc;
   5.502 +      len = sizeof(vendor_desc);
   5.503 +      break;
   5.504 +    case OID_GEN_DRIVER_VERSION:
   5.505 +      temp_data = (NDIS_MINIPORT_MAJOR_VERSION << 8) | NDIS_MINIPORT_MINOR_VERSION;
   5.506 +      len = 2;
   5.507 +      break;
   5.508 +    case OID_GEN_VENDOR_DRIVER_VERSION:
   5.509 +      temp_data = VENDOR_DRIVER_VERSION;
   5.510 +      len = 4;
   5.511 +      break;
   5.512      case OID_TCP_CONNECTION_OFFLOAD_HARDWARE_CAPABILITIES:
   5.513        FUNCTION_MSG("Unhandled OID_TCP_CONNECTION_OFFLOAD_HARDWARE_CAPABILITIES\n");
   5.514        break;
   5.515 @@ -343,6 +715,33 @@ XenNet_QueryInformation(
   5.516      case OID_TCP_OFFLOAD_CURRENT_CONFIG:
   5.517        FUNCTION_MSG("Unhandled OID_TCP_OFFLOAD_CURRENT_CONFIG\n");
   5.518        break;
   5.519 +    case OID_GEN_MAXIMUM_SEND_PACKETS:
   5.520 +      /* this is actually ignored for deserialised drivers like us */
   5.521 +      temp_data = 0;
   5.522 +      break;
   5.523 +    case OID_GEN_HARDWARE_STATUS:
   5.524 +      if (!xi->connected)
   5.525 +      {
   5.526 +        temp_data = NdisHardwareStatusInitializing;
   5.527 +      }
   5.528 +      else
   5.529 +      {
   5.530 +        temp_data = NdisHardwareStatusReady;
   5.531 +      }
   5.532 +      break;
   5.533 +    case OID_GEN_TRANSMIT_BUFFER_SPACE:
   5.534 +      /* multiply this by some small number as we can queue additional packets */
   5.535 +      temp_data = PAGE_SIZE * NET_TX_RING_SIZE * 4;
   5.536 +      break;
   5.537 +    case OID_GEN_RECEIVE_BUFFER_SPACE:
   5.538 +      temp_data = PAGE_SIZE * NET_RX_RING_SIZE * 2;
   5.539 +      break;
   5.540 +    case OID_GEN_TRANSMIT_BLOCK_SIZE:
   5.541 +      temp_data = PAGE_SIZE; //XN_MAX_PKT_SIZE;
   5.542 +      break;
   5.543 +    case OID_GEN_RECEIVE_BLOCK_SIZE:
   5.544 +      temp_data = PAGE_SIZE; //XN_MAX_PKT_SIZE;
   5.545 +      break;
   5.546      default:
   5.547        FUNCTION_MSG("Unhandled get OID_%08x\n", Oid);
   5.548      /* silently fail these */
   5.549 @@ -362,7 +761,7 @@ XenNet_QueryInformation(
   5.550    if (len > InformationBufferLength)
   5.551    {
   5.552      *BytesNeeded = len;
   5.553 -    FUNCTION_MSG("(BUFFER_TOO_SHORT %d > %d)\n", len, InformationBufferLength);
   5.554 +    FUNCTION_MSG("(BUFFER_TOO_SHORT OID_%08x len = %d > InformationBufferLength %d)\n", Oid, len, InformationBufferLength);
   5.555      return NDIS_STATUS_BUFFER_TOO_SHORT;
   5.556    }
   5.557  
   5.558 @@ -965,61 +1364,75 @@ XenNet_SetInformation(
   5.559    //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.560    return status;
   5.561  }
   5.562 -
   5.563 -#if 0
   5.564 -set 0001021a OID_GEN_MACHINE_NAME
   5.565 -get 00010111 OID_GEN_MAXIMUM_TOTAL_SIZE
   5.566 -get 00010209 OID_GEN_INTERRUPT_MODERATION
   5.567 -set 0001010e OID_GEN_CURRENT_PACKET_FILTER
   5.568 -set 0001010f OID_GEN_CURRENT_LOOKAHEAD
   5.569 -get 00010117 OID_GEN_SUPPORTED_GUIDS
   5.570 -
   5.571 -stat 00020101 OID_GEN_XMIT_OK
   5.572  #endif
   5.573  
   5.574  NDIS_STATUS
   5.575  XenNet_OidRequest(NDIS_HANDLE adapter_context, PNDIS_OID_REQUEST oid_request)
   5.576  {
   5.577    NTSTATUS status;
   5.578 +  int i;
   5.579 +  NDIS_OID oid;
   5.580 +  MINIPORT_OID_REQUEST *routine;
   5.581    
   5.582    //FUNCTION_ENTER();
   5.583    switch(oid_request->RequestType)
   5.584    {
   5.585    case NdisRequestQueryInformation:
   5.586 -    //FUNCTION_MSG("RequestType = NdisRequestQueryInformation\n");
   5.587 +    FUNCTION_MSG("RequestType = NdisRequestQueryInformation\n");
   5.588      //FUNCTION_MSG("Oid = %08x\n", oid_request->DATA.QUERY_INFORMATION.Oid);
   5.589 -    status = XenNet_QueryInformation(adapter_context,
   5.590 -      oid_request->DATA.QUERY_INFORMATION.Oid,
   5.591 -      oid_request->DATA.QUERY_INFORMATION.InformationBuffer,
   5.592 -      oid_request->DATA.QUERY_INFORMATION.InformationBufferLength,
   5.593 -      &oid_request->DATA.QUERY_INFORMATION.BytesWritten,
   5.594 -      &oid_request->DATA.QUERY_INFORMATION.BytesNeeded);
   5.595 +    oid = oid_request->DATA.QUERY_INFORMATION.Oid;
   5.596      break;
   5.597    case NdisRequestSetInformation:
   5.598 -    //FUNCTION_MSG("RequestType = NdisRequestSetInformation\n");
   5.599 -    //FUNCTION_MSG("Oid = %08x\n", oid_request->DATA.SET_INFORMATION.Oid);
   5.600 -    status = XenNet_SetInformation(adapter_context,
   5.601 -      oid_request->DATA.SET_INFORMATION.Oid,
   5.602 -      oid_request->DATA.SET_INFORMATION.InformationBuffer,
   5.603 -      oid_request->DATA.SET_INFORMATION.InformationBufferLength,
   5.604 -      &oid_request->DATA.SET_INFORMATION.BytesRead,
   5.605 -      &oid_request->DATA.SET_INFORMATION.BytesNeeded);
   5.606 +    FUNCTION_MSG("RequestType = NdisRequestSetInformation\n");
   5.607 +    oid = oid_request->DATA.SET_INFORMATION.Oid;
   5.608      break;
   5.609    case NdisRequestQueryStatistics:
   5.610 -    //FUNCTION_MSG("RequestType = NdisRequestQueryStatistics\n");
   5.611 -    //FUNCTION_MSG("Oid = %08x\n", oid_request->DATA.METHOD_INFORMATION.Oid);
   5.612 -    status = XenNet_QueryStatistics(adapter_context,
   5.613 -      oid_request->DATA.QUERY_INFORMATION.Oid,
   5.614 -      oid_request->DATA.QUERY_INFORMATION.InformationBuffer,
   5.615 -      oid_request->DATA.QUERY_INFORMATION.InformationBufferLength,
   5.616 -      &oid_request->DATA.QUERY_INFORMATION.BytesWritten,
   5.617 -      &oid_request->DATA.QUERY_INFORMATION.BytesNeeded);
   5.618 +    FUNCTION_MSG("RequestType = NdisRequestQueryStatistics\n");
   5.619 +    oid = oid_request->DATA.QUERY_INFORMATION.Oid;
   5.620      break;
   5.621    default:
   5.622      FUNCTION_MSG("RequestType = NdisRequestQuery%d\n", oid_request->RequestType);
   5.623 -    status = NDIS_STATUS_NOT_SUPPORTED;
   5.624 +    return NDIS_STATUS_NOT_SUPPORTED;
   5.625 +  }
   5.626 +  for (i = 0; xennet_oids[i].oid && xennet_oids[i].oid != oid; i++);
   5.627 +
   5.628 +  if (!xennet_oids[i].oid)
   5.629 +  {
   5.630 +    FUNCTION_MSG("Unsupported OID %08x\n", oid);
   5.631 +    return NDIS_STATUS_NOT_SUPPORTED;
   5.632 +  }
   5.633 +  FUNCTION_MSG("Oid = %s\n", xennet_oids[i].oid_name);
   5.634 +  routine = NULL;
   5.635 +  switch(oid_request->RequestType)
   5.636 +  {
   5.637 +  case NdisRequestQueryInformation:
   5.638 +  case NdisRequestQueryStatistics:
   5.639 +    if (oid_request->DATA.QUERY_INFORMATION.InformationBufferLength < xennet_oids[i].min_length)
   5.640 +    {
   5.641 +      FUNCTION_MSG("InformationBufferLength %d < min_length %d\n", oid_request->DATA.QUERY_INFORMATION.InformationBufferLength < xennet_oids[i].min_length);
   5.642 +      oid_request->DATA.QUERY_INFORMATION.BytesNeeded = xennet_oids[i].min_length;
   5.643 +      return NDIS_STATUS_BUFFER_TOO_SHORT;
   5.644 +    }
   5.645 +    routine =  xennet_oids[i].query_routine;
   5.646 +    break;
   5.647 +  case NdisRequestSetInformation:
   5.648 +    if (oid_request->DATA.SET_INFORMATION.InformationBufferLength < xennet_oids[i].min_length)
   5.649 +    {
   5.650 +      FUNCTION_MSG("InformationBufferLength %d < min_length %d\n", oid_request->DATA.SET_INFORMATION.InformationBufferLength < xennet_oids[i].min_length);
   5.651 +      oid_request->DATA.SET_INFORMATION.BytesNeeded = xennet_oids[i].min_length;
   5.652 +      return NDIS_STATUS_BUFFER_TOO_SHORT;
   5.653 +    }
   5.654 +    routine =  xennet_oids[i].set_routine;
   5.655      break;
   5.656    }
   5.657 +  if (!routine)
   5.658 +  {
   5.659 +    FUNCTION_MSG("Operation not supported\n");
   5.660 +    return NDIS_STATUS_NOT_SUPPORTED;
   5.661 +  }
   5.662 +  status = routine(adapter_context, oid_request);
   5.663 +  FUNCTION_MSG("status = %08x\n", status);
   5.664 +  
   5.665    //FUNCTION_EXIT();
   5.666    return status;
   5.667  }
     6.1 --- a/xennet/xennet6_rx.c	Sun Jul 03 10:28:34 2011 +1000
     6.2 +++ b/xennet/xennet6_rx.c	Sat Jul 09 18:40:28 2011 +1000
     6.3 @@ -124,6 +124,7 @@ get_hb_from_freelist(struct xennet_info 
     6.4  static __inline VOID
     6.5  put_hb_on_freelist(struct xennet_info *xi, shared_buffer_t *hb)
     6.6  {
     6.7 +  ASSERT(xi);
     6.8    hb->mdl->ByteCount = sizeof(shared_buffer_t) + MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH;
     6.9    hb->mdl->Next = NULL;
    6.10    hb->next = NULL;
    6.11 @@ -369,7 +370,24 @@ XenNet_MakePacket(struct xennet_info *xi
    6.12    rc->last_nbl = nbl;
    6.13    NET_BUFFER_LIST_NEXT_NBL(nbl) = NULL;
    6.14    InterlockedIncrement(&xi->rx_outstanding);
    6.15 -
    6.16 +  if (pi->is_multicast)
    6.17 +  {
    6.18 +    /* multicast */
    6.19 +    xi->stats.ifHCInMulticastPkts++;
    6.20 +    xi->stats.ifHCInMulticastOctets += NET_BUFFER_DATA_LENGTH(nb);
    6.21 +  }
    6.22 +  else if (pi->is_broadcast)
    6.23 +  {
    6.24 +    /* broadcast */
    6.25 +    xi->stats.ifHCInBroadcastPkts++;
    6.26 +    xi->stats.ifHCInBroadcastOctets += NET_BUFFER_DATA_LENGTH(nb);
    6.27 +  }
    6.28 +  else
    6.29 +  {
    6.30 +    /* unicast */
    6.31 +    xi->stats.ifHCInUcastPkts++;
    6.32 +    xi->stats.ifHCInUcastOctets += NET_BUFFER_DATA_LENGTH(nb);
    6.33 +  }
    6.34    //FUNCTION_EXIT();
    6.35    return TRUE;
    6.36  }
    6.37 @@ -550,7 +568,7 @@ XenNet_MakePackets(struct xennet_info *x
    6.38      if (!XenNet_MakePacket(xi, rc, pi))
    6.39      {
    6.40        KdPrint((__DRIVER_NAME "     Ran out of packets\n"));
    6.41 -      xi->stat_rx_no_buffer++;
    6.42 +      xi->stats.ifInDiscards++;
    6.43        goto done;
    6.44      }
    6.45      goto done;
    6.46 @@ -558,7 +576,7 @@ XenNet_MakePackets(struct xennet_info *x
    6.47      if (!XenNet_MakePacket(xi, rc, pi))
    6.48      {
    6.49        KdPrint((__DRIVER_NAME "     Ran out of packets\n"));
    6.50 -      xi->stat_rx_no_buffer++;
    6.51 +      xi->stats.ifInDiscards++;
    6.52        goto done;
    6.53      }
    6.54      goto done;
    6.55 @@ -574,7 +592,7 @@ XenNet_MakePackets(struct xennet_info *x
    6.56      if (!XenNet_MakePacket(xi, rc, pi))
    6.57      {
    6.58        KdPrint((__DRIVER_NAME "     Ran out of packets\n"));
    6.59 -      xi->stat_rx_no_buffer++;
    6.60 +      xi->stats.ifInDiscards++;
    6.61        break; /* we are out of memory - just drop the packets */
    6.62      }
    6.63      if (psh)
    6.64 @@ -614,6 +632,7 @@ XenNet_ReturnNetBufferLists(NDIS_HANDLE 
    6.65  
    6.66    //KdPrint((__DRIVER_NAME "     page_buf = %p\n", page_buf));
    6.67  
    6.68 +  ASSERT(xi);
    6.69    while (curr_nbl)
    6.70    {
    6.71      PNET_BUFFER_LIST next_nbl;
    6.72 @@ -924,8 +943,6 @@ XenNet_RxBufferCheck(struct xennet_info 
    6.73    }
    6.74    ASSERT(!more_data_flag && !extra_info_flag);
    6.75  
    6.76 -  xi->stat_rx_ok += packet_count;
    6.77 -
    6.78    if (rc.first_nbl)
    6.79    {
    6.80      NdisMIndicateReceiveNetBufferLists(xi->adapter_handle, rc.first_nbl, NDIS_DEFAULT_PORT_NUMBER, nbl_count,
    6.81 @@ -1028,7 +1045,7 @@ XenNet_RxInit(xennet_info_t *xi)
    6.82  {
    6.83    NET_BUFFER_LIST_POOL_PARAMETERS nbl_pool_parameters;
    6.84    NET_BUFFER_POOL_PARAMETERS nb_pool_parameters;
    6.85 -  UNREFERENCED_PARAMETER(xi);
    6.86 +  int ret;
    6.87  
    6.88    FUNCTION_ENTER();
    6.89  
    6.90 @@ -1043,8 +1060,21 @@ XenNet_RxInit(xennet_info_t *xi)
    6.91    }
    6.92    NdisZeroMemory(xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount());
    6.93  
    6.94 -  stack_new(&xi->rx_pb_stack, NET_RX_RING_SIZE * 4);
    6.95 +  ret = stack_new(&xi->rx_pb_stack, NET_RX_RING_SIZE * 4);
    6.96 +  if (!ret)
    6.97 +  {
    6.98 +    FUNCTION_MSG("Failed to allocate rx_pb_stack\n");
    6.99 +    NdisFreeMemory(xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount(), 0);
   6.100 +    return FALSE;
   6.101 +  }
   6.102    stack_new(&xi->rx_hb_stack, NET_RX_RING_SIZE * 4);
   6.103 +  if (!ret)
   6.104 +  {
   6.105 +    FUNCTION_MSG("Failed to allocate rx_hb_stack\n");
   6.106 +    stack_delete(xi->rx_pb_stack, NULL, NULL);
   6.107 +    NdisFreeMemory(xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount(), 0);
   6.108 +    return FALSE;
   6.109 +  }
   6.110  
   6.111    XenNet_BufferAlloc(xi);
   6.112    
   6.113 @@ -1063,7 +1093,6 @@ XenNet_RxInit(xennet_info_t *xi)
   6.114      KdPrint(("NdisAllocateNetBufferListPool failed\n"));
   6.115      return FALSE;
   6.116    }
   6.117 -  //stack_new(&xi->rx_packet_stack, NET_RX_RING_SIZE * 4);
   6.118  
   6.119    nb_pool_parameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
   6.120    nb_pool_parameters.Header.Revision = NET_BUFFER_POOL_PARAMETERS_REVISION_1;
     7.1 --- a/xennet/xennet6_tx.c	Sun Jul 03 10:28:34 2011 +1000
     7.2 +++ b/xennet/xennet6_tx.c	Sat Jul 09 18:40:28 2011 +1000
     7.3 @@ -409,8 +409,6 @@ XenNet_HWSendPacket(struct xennet_info *
     7.4      break;
     7.5    }
     7.6  
     7.7 -  xi->stat_tx_ok++;
     7.8 -
     7.9    //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
    7.10    //FUNCTION_EXIT();
    7.11    xi->tx_outstanding++;
    7.12 @@ -429,13 +427,13 @@ XenNet_SendQueuedPackets(struct xennet_i
    7.13  
    7.14    //FUNCTION_ENTER();
    7.15  
    7.16 +  ASSERT(!KeTestSpinLock(&xi->tx_lock));
    7.17    if (xi->device_state->suspend_resume_state_pdo != SR_STATE_RUNNING)
    7.18      return;
    7.19  
    7.20 -  nb_entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
    7.21 -  /* if empty, the above returns head*, not NULL */
    7.22 -  while (nb_entry != &xi->tx_waiting_pkt_list)
    7.23 +  while (!IsListEmpty(&xi->tx_waiting_pkt_list))
    7.24    {
    7.25 +    nb_entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
    7.26      nb = CONTAINING_RECORD(nb_entry, NET_BUFFER, NB_LIST_ENTRY_FIELD);
    7.27      
    7.28      if (!XenNet_HWSendPacket(xi, nb))
    7.29 @@ -444,7 +442,6 @@ XenNet_SendQueuedPackets(struct xennet_i
    7.30        InsertHeadList(&xi->tx_waiting_pkt_list, nb_entry);
    7.31        break;
    7.32      }
    7.33 -    nb_entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
    7.34    }
    7.35  
    7.36    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xi->tx, notify);
    7.37 @@ -460,8 +457,9 @@ VOID
    7.38  XenNet_TxBufferGC(struct xennet_info *xi, BOOLEAN dont_set_event)
    7.39  {
    7.40    RING_IDX cons, prod;
    7.41 -  LIST_ENTRY nb_head;
    7.42 -  PLIST_ENTRY nb_entry;
    7.43 +  PNET_BUFFER_LIST nbl_head = NULL;
    7.44 +  PNET_BUFFER_LIST nbl_tail = NULL;  
    7.45 +  PNET_BUFFER_LIST nbl;
    7.46    PNET_BUFFER nb;
    7.47    ULONG tx_packets = 0;
    7.48  
    7.49 @@ -473,7 +471,7 @@ XenNet_TxBufferGC(struct xennet_info *xi
    7.50  
    7.51    KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
    7.52  
    7.53 -  InitializeListHead(&nb_head);
    7.54 +//  InitializeListHead(&nbl_head);
    7.55    if (xi->tx_shutting_down && !xi->tx_outstanding)
    7.56    {
    7.57      /* there is a chance that our Dpc had been queued just before the shutdown... */
    7.58 @@ -516,19 +514,58 @@ XenNet_TxBufferGC(struct xennet_info *xi
    7.59        
    7.60        if (shadow->nb)
    7.61        {
    7.62 -        PLIST_ENTRY nb_entry;
    7.63 -        //KdPrint((__DRIVER_NAME "     nb %p complete\n"));
    7.64 +        PMDL mdl;
    7.65 +        PUCHAR header;
    7.66          nb = shadow->nb;
    7.67 -        nb_entry = &NB_LIST_ENTRY(nb);
    7.68 -        InsertTailList(&nb_head, nb_entry);
    7.69 +        mdl = NET_BUFFER_CURRENT_MDL(nb);
    7.70 +        header = MmGetSystemAddressForMdlSafe(mdl, LowPagePriority); /* already mapped so guaranteed to work */
    7.71 +        header += NET_BUFFER_CURRENT_MDL_OFFSET(nb);
    7.72 +
    7.73 +        xi->stats.ifHCOutOctets += nb->DataLength;
    7.74 +        if (nb->DataLength < XN_HDR_SIZE || !(header[0] & 0x01))
    7.75 +        {
    7.76 +          /* unicast or tiny packet */
    7.77 +          xi->stats.ifHCOutUcastPkts++;
    7.78 +          xi->stats.ifHCOutUcastOctets += nb->DataLength;
    7.79 +        }
    7.80 +        else if (header[0] == 0xFF && header[1] == 0xFF && header[2] == 0xFF
    7.81 +          && header[3] == 0xFF && header[4] == 0xFF && header[5] == 0xFF)
    7.82 +        {
    7.83 +          /* broadcast */
    7.84 +          xi->stats.ifHCOutBroadcastPkts++;
    7.85 +          xi->stats.ifHCOutBroadcastOctets += nb->DataLength;
    7.86 +        }
    7.87 +        else
    7.88 +        {
    7.89 +          /* multicast */
    7.90 +          xi->stats.ifHCOutMulticastPkts++;
    7.91 +          xi->stats.ifHCOutMulticastOctets += nb->DataLength;
    7.92 +        }
    7.93 +        
    7.94 +        nbl = NB_NBL(nb);
    7.95 +        NBL_REF(nbl)--;
    7.96 +        if (!NBL_REF(nbl))
    7.97 +        {
    7.98 +          NET_BUFFER_LIST_NEXT_NBL(nbl) = NULL;
    7.99 +          if (nbl_head)
   7.100 +          {
   7.101 +            NET_BUFFER_LIST_NEXT_NBL(nbl_tail) = nbl;
   7.102 +            nbl_tail = nbl;
   7.103 +          }
   7.104 +          else
   7.105 +          {
   7.106 +            nbl_head = nbl;
   7.107 +            nbl_tail = nbl;
   7.108 +          }
   7.109 +        }
   7.110          shadow->nb = NULL;
   7.111 +        tx_packets++;
   7.112        }
   7.113        put_id_on_freelist(xi, txrsp->id);
   7.114      }
   7.115  
   7.116      xi->tx.rsp_cons = prod;
   7.117      /* resist the temptation to set the event more than +1... it breaks things */
   7.118 -    /* although I think we could set it to higher if we knew there were more outstanding packets coming soon... */
   7.119      if (!dont_set_event)
   7.120        xi->tx.sring->rsp_event = prod + 1;
   7.121      KeMemoryBarrier();
   7.122 @@ -541,23 +578,9 @@ XenNet_TxBufferGC(struct xennet_info *xi
   7.123    KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
   7.124  
   7.125    /* must be done without holding any locks */
   7.126 -  nb_entry = RemoveHeadList(&nb_head);
   7.127 -  /* if empty, the above returns head*, not NULL */
   7.128 -  while (nb_entry != &nb_head)
   7.129 -  {
   7.130 -    PNET_BUFFER_LIST nbl;
   7.131 -    nb = CONTAINING_RECORD(nb_entry, NET_BUFFER, NB_LIST_ENTRY_FIELD);
   7.132 -    nbl = NB_NBL(nb);
   7.133 -    NBL_REF(nbl)--;
   7.134 -    if (!NBL_REF(nbl))
   7.135 -    {
   7.136 -      nbl->Status = NDIS_STATUS_SUCCESS;
   7.137 -      NdisMSendNetBufferListsComplete(xi->adapter_handle, nbl, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
   7.138 -    }
   7.139 -    tx_packets++;
   7.140 -    nb_entry = RemoveHeadList(&nb_head);
   7.141 -  }
   7.142 -
   7.143 +  if (nbl_head)
   7.144 +    NdisMSendNetBufferListsComplete(xi->adapter_handle, nbl_head, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
   7.145 +  
   7.146    /* must be done after we have truly given back all packets */
   7.147    KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
   7.148    xi->tx_outstanding -= tx_packets;
   7.149 @@ -590,6 +613,7 @@ XenNet_SendNetBufferLists(
   7.150    PLIST_ENTRY nb_entry;
   7.151    KIRQL old_irql;
   7.152    PNET_BUFFER_LIST curr_nbl;
   7.153 +  PNET_BUFFER_LIST next_nbl;
   7.154  
   7.155    UNREFERENCED_PARAMETER(port_number);
   7.156    //FUNCTION_ENTER();
   7.157 @@ -597,24 +621,24 @@ XenNet_SendNetBufferLists(
   7.158    if (xi->inactive)
   7.159    {
   7.160      curr_nbl = nb_lists;
   7.161 -    while(curr_nbl)
   7.162 +    for (curr_nbl = nb_lists; curr_nbl; curr_nbl = NET_BUFFER_LIST_NEXT_NBL(curr_nbl))
   7.163      {
   7.164 -      PNET_BUFFER_LIST next_nbl = NET_BUFFER_LIST_NEXT_NBL(curr_nbl);
   7.165 -      NET_BUFFER_LIST_NEXT_NBL(curr_nbl) = NULL;
   7.166        KdPrint((__DRIVER_NAME "     NBL %p\n", curr_nbl));
   7.167        curr_nbl->Status = NDIS_STATUS_FAILURE;
   7.168 -      NdisMSendNetBufferListsComplete(xi->adapter_handle, curr_nbl, (send_flags & NDIS_SEND_FLAGS_DISPATCH_LEVEL)?NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL:0);
   7.169 -      curr_nbl = next_nbl;
   7.170      }
   7.171 +    /* this actions the whole list */
   7.172 +    NdisMSendNetBufferListsComplete(xi->adapter_handle, nb_lists, (send_flags & NDIS_SEND_FLAGS_DISPATCH_LEVEL)?NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL:0);
   7.173      return;
   7.174    }
   7.175  
   7.176    KeAcquireSpinLock(&xi->tx_lock, &old_irql);
   7.177    
   7.178 -  for (curr_nbl = nb_lists; curr_nbl; curr_nbl = NET_BUFFER_LIST_NEXT_NBL(curr_nbl))
   7.179 +  for (curr_nbl = nb_lists; curr_nbl; curr_nbl = next_nbl)
   7.180    {
   7.181      PNET_BUFFER curr_nb;
   7.182      NBL_REF(curr_nbl) = 0;
   7.183 +    next_nbl = NET_BUFFER_LIST_NEXT_NBL(curr_nbl);
   7.184 +    NET_BUFFER_LIST_NEXT_NBL(curr_nbl) = NULL;
   7.185      for (curr_nb = NET_BUFFER_LIST_FIRST_NB(curr_nbl); curr_nb; curr_nb = NET_BUFFER_NEXT_NB(curr_nb))
   7.186      {
   7.187        NB_NBL(curr_nb) = curr_nbl;
   7.188 @@ -753,6 +777,7 @@ XenNet_TxShutdown(xennet_info_t *xi)
   7.189    PNET_BUFFER nb;
   7.190    PNET_BUFFER_LIST nbl;
   7.191    PLIST_ENTRY nb_entry;
   7.192 +  LARGE_INTEGER timeout;
   7.193  
   7.194    FUNCTION_ENTER();
   7.195  
   7.196 @@ -763,16 +788,16 @@ XenNet_TxShutdown(xennet_info_t *xi)
   7.197    while (xi->tx_outstanding)
   7.198    {
   7.199      KdPrint((__DRIVER_NAME "     Waiting for %d remaining packets to be sent\n", xi->tx_outstanding));
   7.200 -    KeWaitForSingleObject(&xi->tx_idle_event, Executive, KernelMode, FALSE, NULL);
   7.201 +    timeout.QuadPart = -1 * 1 * 1000 * 1000 * 10; /* 1 second */
   7.202 +    KeWaitForSingleObject(&xi->tx_idle_event, Executive, KernelMode, FALSE, &timeout);
   7.203    }
   7.204  
   7.205    KeFlushQueuedDpcs();
   7.206  
   7.207    /* Free packets in tx queue */
   7.208 -  nb_entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
   7.209 -  /* if empty, the above returns head*, not NULL */
   7.210 -  while (nb_entry != &xi->tx_waiting_pkt_list)
   7.211 +  while (!IsListEmpty(&xi->tx_waiting_pkt_list))
   7.212    {
   7.213 +    nb_entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
   7.214      nb = CONTAINING_RECORD(nb_entry, NET_BUFFER, NB_LIST_ENTRY_FIELD);
   7.215      nbl = NB_NBL(nb);
   7.216      NBL_REF(nbl)--;
   7.217 @@ -781,7 +806,6 @@ XenNet_TxShutdown(xennet_info_t *xi)
   7.218        nbl->Status = NDIS_STATUS_FAILURE;
   7.219        NdisMSendNetBufferListsComplete(xi->adapter_handle, nbl, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
   7.220      }
   7.221 -    nb_entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
   7.222    }
   7.223    NdisDeleteNPagedLookasideList(&xi->tx_lookaside_list);
   7.224