win-pvdrivers

changeset 918:20d89c3113ec

Updates to NDIS6 interface. TX appears to be working well. RX is broken for LSO.
author James Harper <james.harper@bendigoit.com.au>
date Thu May 05 22:39:13 2011 +1000 (2011-05-05)
parents 7321f245acc6
children ebffcc1112a3
files 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/xennet6.c	Mon May 02 00:18:22 2011 +1000
     1.2 +++ b/xennet/xennet6.c	Thu May 05 22:39:13 2011 +1000
     1.3 @@ -332,11 +332,11 @@ XenNet_RxTxDpc(PKDPC dpc, PVOID context,
     1.4    UNREFERENCED_PARAMETER(arg1);
     1.5    UNREFERENCED_PARAMETER(arg2);
     1.6  
     1.7 -  FUNCTION_ENTER();
     1.8 +  //FUNCTION_ENTER();
     1.9    /* 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 */
    1.10    dont_set_event = XenNet_RxBufferCheck(xi);
    1.11    XenNet_TxBufferGC(xi, dont_set_event);
    1.12 -  FUNCTION_EXIT();
    1.13 +  //FUNCTION_EXIT();
    1.14  } 
    1.15  
    1.16  static BOOLEAN
    1.17 @@ -487,39 +487,45 @@ XenNet_D0Entry(struct xennet_info *xi)
    1.18  
    1.19    return status;
    1.20  }
    1.21 -
    1.22 -NDIS_OID supported_oids[] =
    1.23 +static NDIS_OID supported_oids[] =
    1.24  {
    1.25 -  /* general OIDs */
    1.26 -  OID_GEN_SUPPORTED_LIST,        // Q
    1.27 +  /* mandatory */
    1.28    OID_GEN_HARDWARE_STATUS,       // Q
    1.29 -  OID_GEN_MEDIA_SUPPORTED,       // Q
    1.30 -  OID_GEN_MEDIA_IN_USE,          // Q
    1.31 -  OID_GEN_MAXIMUM_LOOKAHEAD,     // Q
    1.32 -  OID_GEN_MAXIMUM_FRAME_SIZE,    // Q
    1.33 -  //OID_GEN_LINK_SPEED,            // Q
    1.34 +
    1.35    OID_GEN_TRANSMIT_BUFFER_SPACE, // Q
    1.36    OID_GEN_RECEIVE_BUFFER_SPACE,  // Q
    1.37    OID_GEN_TRANSMIT_BLOCK_SIZE,   // Q
    1.38    OID_GEN_RECEIVE_BLOCK_SIZE,    // Q
    1.39 +
    1.40    OID_GEN_VENDOR_ID,             // Q
    1.41    OID_GEN_VENDOR_DESCRIPTION,    // Q
    1.42 +  OID_GEN_VENDOR_DRIVER_VERSION, // Q
    1.43 +
    1.44    OID_GEN_CURRENT_PACKET_FILTER, // QS
    1.45    OID_GEN_CURRENT_LOOKAHEAD,     // QS
    1.46    OID_GEN_DRIVER_VERSION,        // Q
    1.47 -  OID_GEN_VENDOR_DRIVER_VERSION, // Q
    1.48    OID_GEN_MAXIMUM_TOTAL_SIZE,    // Q
    1.49 -  OID_GEN_PROTOCOL_OPTIONS,      // S
    1.50 -  OID_GEN_MAC_OPTIONS,           // Q
    1.51 -  OID_GEN_MEDIA_CONNECT_STATUS,  // Q
    1.52 -  OID_GEN_MAXIMUM_SEND_PACKETS,  // Q
    1.53 +  OID_GEN_LINK_PARAMETERS,       // S
    1.54 +  OID_GEN_INTERRUPT_MODERATION,  // QS
    1.55 +  
    1.56 +  /* general optional */
    1.57 +  OID_GEN_NETWORK_LAYER_ADDRESSES,       
    1.58 +  OID_GEN_TRANSPORT_HEADER_OFFSET,
    1.59 +
    1.60 +  /* power */
    1.61 +  OID_PNP_CAPABILITIES,
    1.62 +  OID_PNP_SET_POWER,
    1.63 +  OID_PNP_QUERY_POWER,
    1.64 +  
    1.65    /* stats */
    1.66 -  OID_GEN_XMIT_OK,               // Q
    1.67 -  OID_GEN_RCV_OK,                // Q
    1.68 -  OID_GEN_XMIT_ERROR,            // Q
    1.69 -  OID_GEN_RCV_ERROR,             // Q
    1.70 -  OID_GEN_RCV_NO_BUFFER,         // Q
    1.71 -  /* media-specific OIDs */
    1.72 +  OID_GEN_XMIT_OK,
    1.73 +  OID_GEN_RCV_OK,
    1.74 +  OID_GEN_XMIT_ERROR,
    1.75 +  OID_GEN_RCV_ERROR,
    1.76 +  OID_GEN_RCV_NO_BUFFER,
    1.77 +  OID_GEN_STATISTICS,
    1.78 +  
    1.79 +  /* media-specific */
    1.80    OID_802_3_PERMANENT_ADDRESS,
    1.81    OID_802_3_CURRENT_ADDRESS,
    1.82    OID_802_3_MULTICAST_LIST,
    1.83 @@ -527,12 +533,11 @@ NDIS_OID supported_oids[] =
    1.84    OID_802_3_RCV_ERROR_ALIGNMENT,
    1.85    OID_802_3_XMIT_ONE_COLLISION,
    1.86    OID_802_3_XMIT_MORE_COLLISIONS,
    1.87 +  
    1.88    /* tcp offload */
    1.89    OID_TCP_TASK_OFFLOAD,
    1.90 -  /* power */
    1.91 -  OID_PNP_CAPABILITIES,
    1.92 -  OID_PNP_SET_POWER,
    1.93 -  OID_PNP_QUERY_POWER,
    1.94 +  OID_TCP_OFFLOAD_PARAMETERS,
    1.95 +  OID_OFFLOAD_ENCAPSULATION,
    1.96  };
    1.97  
    1.98  // Called at <= DISPATCH_LEVEL
    1.99 @@ -560,7 +565,10 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   1.100    ULONG qemu_hide_flags_value = 0;
   1.101    NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES registration_attributes;
   1.102    NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES general_attributes;
   1.103 -  
   1.104 +  NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES offload_attributes;
   1.105 +  NDIS_OFFLOAD df_offload, hw_offload;
   1.106 +  NDIS_TCP_CONNECTION_OFFLOAD df_conn_offload, hw_conn_offload;
   1.107 +
   1.108    UNREFERENCED_PARAMETER(driver_context);
   1.109  
   1.110    FUNCTION_ENTER();
   1.111 @@ -820,6 +828,9 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   1.112      KdPrint(("Failed to go to D0 (%08x)\n", status));
   1.113      goto err;
   1.114    }
   1.115 +  
   1.116 +  xi->current_csum_ipv4 = xi->config_csum;
   1.117 +  xi->current_lso_ipv4 = xi->config_gso;
   1.118  
   1.119    registration_attributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
   1.120    registration_attributes.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
   1.121 @@ -905,6 +916,94 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   1.122      KdPrint(("NdisMSetMiniportAttributes(general) failed (%08x)\n", status));
   1.123      goto err;
   1.124    }
   1.125 +  
   1.126 +  /* this is the initial offload state */
   1.127 +  RtlZeroMemory(&df_offload, sizeof(df_offload));
   1.128 +  df_offload.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
   1.129 +  df_offload.Header.Revision = NDIS_OFFLOAD_REVISION_1; // revision 2 does exist
   1.130 +  df_offload.Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;
   1.131 +  df_offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
   1.132 +  df_offload.Checksum.IPv4Transmit.IpOptionsSupported = NDIS_OFFLOAD_SET_ON;
   1.133 +  df_offload.Checksum.IPv4Transmit.TcpOptionsSupported = NDIS_OFFLOAD_SET_ON;
   1.134 +  df_offload.Checksum.IPv4Transmit.TcpChecksum = NDIS_OFFLOAD_SET_ON;
   1.135 +  df_offload.Checksum.IPv4Transmit.UdpChecksum = NDIS_OFFLOAD_SET_ON;
   1.136 +  df_offload.Checksum.IPv4Transmit.IpChecksum = NDIS_OFFLOAD_SET_ON;
   1.137 +  df_offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
   1.138 +  df_offload.Checksum.IPv4Receive.IpOptionsSupported = NDIS_OFFLOAD_SET_ON;
   1.139 +  df_offload.Checksum.IPv4Receive.TcpOptionsSupported = NDIS_OFFLOAD_SET_ON;
   1.140 +  df_offload.Checksum.IPv4Receive.TcpChecksum = NDIS_OFFLOAD_SET_ON;
   1.141 +  df_offload.Checksum.IPv4Receive.UdpChecksum = NDIS_OFFLOAD_SET_ON;
   1.142 +  df_offload.Checksum.IPv4Receive.IpChecksum = NDIS_OFFLOAD_SET_ON;
   1.143 +  /* offload.Checksum.IPv6Transmit is not supported */
   1.144 +  /* offload.Checksum.IPv6Receive is not supported */
   1.145 +  df_offload.LsoV1.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
   1.146 +  df_offload.LsoV1.IPv4.MaxOffLoadSize = xi->config_gso;
   1.147 +  df_offload.LsoV1.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
   1.148 +  df_offload.LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */
   1.149 +  df_offload.LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */
   1.150 +  df_offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
   1.151 +  df_offload.LsoV2.IPv4.MaxOffLoadSize = xi->config_gso;
   1.152 +  df_offload.LsoV2.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
   1.153 +  /* df_offload.LsoV2.IPv6 is not supported */
   1.154 +  /* df_offload.IPsecV1 is not supported */
   1.155 +  df_offload.Flags = 0;
   1.156 +  /* df_offload.IPsecV2 is not supported */
   1.157 +
   1.158 +  /* this is the supported offload state */
   1.159 +  RtlZeroMemory(&hw_offload, sizeof(hw_offload));
   1.160 +  hw_offload.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
   1.161 +  hw_offload.Header.Revision = NDIS_OFFLOAD_REVISION_1; // revision 2 does exist
   1.162 +  hw_offload.Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;
   1.163 +  hw_offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
   1.164 +  hw_offload.Checksum.IPv4Transmit.IpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;
   1.165 +  hw_offload.Checksum.IPv4Transmit.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;
   1.166 +  hw_offload.Checksum.IPv4Transmit.TcpChecksum = NDIS_OFFLOAD_SUPPORTED;
   1.167 +  hw_offload.Checksum.IPv4Transmit.UdpChecksum = NDIS_OFFLOAD_SUPPORTED;
   1.168 +  hw_offload.Checksum.IPv4Transmit.IpChecksum = NDIS_OFFLOAD_SUPPORTED;
   1.169 +  hw_offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
   1.170 +  hw_offload.Checksum.IPv4Receive.IpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;
   1.171 +  hw_offload.Checksum.IPv4Receive.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;
   1.172 +  hw_offload.Checksum.IPv4Receive.TcpChecksum = NDIS_OFFLOAD_SUPPORTED;
   1.173 +  hw_offload.Checksum.IPv4Receive.UdpChecksum = NDIS_OFFLOAD_SUPPORTED;
   1.174 +  hw_offload.Checksum.IPv4Receive.IpChecksum = NDIS_OFFLOAD_SUPPORTED;
   1.175 +  /* hw_offload.Checksum.IPv6Transmit is not supported */
   1.176 +  /* hw_offload.Checksum.IPv6Receive is not supported */
   1.177 +  hw_offload.LsoV1.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
   1.178 +  hw_offload.LsoV1.IPv4.MaxOffLoadSize = xi->config_gso;
   1.179 +  hw_offload.LsoV1.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
   1.180 +  hw_offload.LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */
   1.181 +  hw_offload.LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */
   1.182 +  hw_offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
   1.183 +  hw_offload.LsoV2.IPv4.MaxOffLoadSize = xi->config_gso;
   1.184 +  hw_offload.LsoV2.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
   1.185 +  /* hw_offload.LsoV2.IPv6 is not supported */
   1.186 +  /* hw_offload.IPsecV1 is not supported */
   1.187 +  hw_offload.Flags = 0;
   1.188 +  /* hw_offload.IPsecV2 is not supported */
   1.189 +  
   1.190 +  RtlZeroMemory(&df_conn_offload, sizeof(df_conn_offload));
   1.191 +  df_conn_offload.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
   1.192 +  df_conn_offload.Header.Revision = NDIS_TCP_CONNECTION_OFFLOAD_REVISION_1;
   1.193 +  df_conn_offload.Header.Size = NDIS_SIZEOF_TCP_CONNECTION_OFFLOAD_REVISION_1;
   1.194 +
   1.195 +  RtlZeroMemory(&hw_conn_offload, sizeof(hw_conn_offload));
   1.196 +  hw_conn_offload.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
   1.197 +  hw_conn_offload.Header.Revision = NDIS_TCP_CONNECTION_OFFLOAD_REVISION_1;
   1.198 +  hw_conn_offload.Header.Size = NDIS_SIZEOF_TCP_CONNECTION_OFFLOAD_REVISION_1;
   1.199 +  
   1.200 +  offload_attributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES;
   1.201 +  offload_attributes.Header.Revision = NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
   1.202 +  offload_attributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
   1.203 +  offload_attributes.DefaultOffloadConfiguration = &df_offload;
   1.204 +  offload_attributes.HardwareOffloadCapabilities = &hw_offload;
   1.205 +  offload_attributes.DefaultTcpConnectionOffloadConfiguration = &df_conn_offload;
   1.206 +  offload_attributes.TcpConnectionOffloadHardwareCapabilities  = &hw_conn_offload;
   1.207 +  status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&offload_attributes);
   1.208 +  if (!NT_SUCCESS(status))
   1.209 +  {
   1.210 +    KdPrint(("NdisMSetMiniportAttributes(offload) failed (%08x)\n", status));
   1.211 +    goto err;
   1.212 +  }
   1.213  
   1.214    return NDIS_STATUS_SUCCESS;
   1.215    
     2.1 --- a/xennet/xennet6.h	Mon May 02 00:18:22 2011 +1000
     2.2 +++ b/xennet/xennet6.h	Thu May 05 22:39:13 2011 +1000
     2.3 @@ -214,21 +214,23 @@ typedef struct
     2.4  
     2.5  typedef struct {
     2.6    PMDL first_mdl;
     2.7 +  MDL first_mdl_storage;
     2.8 +  PPFN_NUMBER first_mdl_pfns[17]; /* maximum possible packet size */
     2.9    PMDL curr_mdl;
    2.10    shared_buffer_t *first_pb;
    2.11    shared_buffer_t *curr_pb;
    2.12    PUCHAR first_mdl_virtual;
    2.13    //ULONG mdl_count;
    2.14    ULONG first_mdl_offset;
    2.15 +  ULONG first_mdl_length;
    2.16    ULONG curr_mdl_offset;
    2.17    USHORT mss;
    2.18    //NDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
    2.19 -  //BOOLEAN csum_blank;
    2.20 -  //BOOLEAN data_validated;
    2.21 +  BOOLEAN csum_blank;
    2.22 +  BOOLEAN data_validated;
    2.23    BOOLEAN split_required;
    2.24    UCHAR ip_version;
    2.25    PUCHAR header;
    2.26 -  ULONG first_mdl_length;
    2.27    ULONG header_length;
    2.28    UCHAR ip_proto;
    2.29    ULONG total_length;
    2.30 @@ -314,8 +316,9 @@ struct xennet_info
    2.31    NDIS_HANDLE rx_nbl_pool;
    2.32    NDIS_HANDLE rx_nb_pool;
    2.33    volatile LONG rx_pb_free;
    2.34 -  //struct stack_state *rx_packet_stack;
    2.35    struct stack_state *rx_pb_stack;
    2.36 +  volatile LONG rx_hb_free;
    2.37 +  struct stack_state *rx_hb_stack;
    2.38    shared_buffer_t *rx_ring_pbs[NET_RX_RING_SIZE];
    2.39    NPAGED_LOOKASIDE_LIST rx_lookaside_list;
    2.40    /* Receive-ring batched refills. */
    2.41 @@ -338,8 +341,8 @@ struct xennet_info
    2.42    ULONG config_mtu;
    2.43    ULONG config_rx_interrupt_moderation;
    2.44  
    2.45 -  //NDIS_TASK_TCP_IP_CHECKSUM setting_csum;
    2.46 -  ULONG setting_max_offload;
    2.47 +  BOOLEAN current_csum_ipv4;
    2.48 +  ULONG current_lso_ipv4;
    2.49  
    2.50    /* config stuff calculated from the above */
    2.51    ULONG config_max_pkt_size;
     3.1 --- a/xennet/xennet6_common.c	Mon May 02 00:18:22 2011 +1000
     3.2 +++ b/xennet/xennet6_common.c	Thu May 05 22:39:13 2011 +1000
     3.3 @@ -26,14 +26,14 @@ XenNet_BuildHeader(packet_info_t *pi, PU
     3.4  {
     3.5    ULONG bytes_remaining;
     3.6  
     3.7 -  FUNCTION_ENTER();
     3.8 +  //FUNCTION_ENTER();
     3.9  
    3.10    if (!header)
    3.11      header = pi->header;
    3.12  
    3.13    if (new_header_size <= pi->header_length)
    3.14    {
    3.15 -    FUNCTION_EXIT();
    3.16 +    //FUNCTION_EXIT();
    3.17      return TRUE; /* header is already at least the required size */
    3.18    }
    3.19  
    3.20 @@ -42,11 +42,11 @@ XenNet_BuildHeader(packet_info_t *pi, PU
    3.21      /* still working in the first buffer */
    3.22      if (new_header_size <= pi->first_mdl_length)
    3.23      {
    3.24 -      KdPrint((__DRIVER_NAME "     new_header_size <= pi->first_mdl_length\n"));
    3.25 +      //KdPrint((__DRIVER_NAME "     new_header_size <= pi->first_mdl_length\n"));
    3.26        pi->header_length = new_header_size;
    3.27        if (pi->header_length == pi->first_mdl_length)
    3.28        {
    3.29 -        NdisGetNextBuffer(pi->curr_mdl, &pi->curr_mdl);
    3.30 +        NdisGetNextMdl(pi->curr_mdl, &pi->curr_mdl);
    3.31          pi->curr_mdl_offset = 0;
    3.32          if (pi->curr_pb)
    3.33            pi->curr_pb = pi->curr_pb->next;
    3.34 @@ -55,12 +55,12 @@ XenNet_BuildHeader(packet_info_t *pi, PU
    3.35        {
    3.36          pi->curr_mdl_offset = (USHORT)new_header_size;
    3.37        }
    3.38 -      FUNCTION_EXIT();
    3.39 +      //FUNCTION_EXIT();
    3.40        return TRUE;
    3.41      }
    3.42      else
    3.43      {
    3.44 -      KdPrint((__DRIVER_NAME "     Switching to header_data\n"));
    3.45 +      //KdPrint((__DRIVER_NAME "     Switching to header_data\n"));
    3.46        memcpy(pi->header_data, header, pi->header_length);
    3.47        header = pi->header = pi->header_data;
    3.48      }
    3.49 @@ -69,24 +69,24 @@ XenNet_BuildHeader(packet_info_t *pi, PU
    3.50    bytes_remaining = new_header_size - pi->header_length;
    3.51    // 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
    3.52  
    3.53 -  KdPrint((__DRIVER_NAME "     A bytes_remaining = %d, pi->curr_mdl = %p\n", bytes_remaining, pi->curr_mdl));
    3.54 +  //KdPrint((__DRIVER_NAME "     A bytes_remaining = %d, pi->curr_mdl = %p\n", bytes_remaining, pi->curr_mdl));
    3.55    while (bytes_remaining && pi->curr_mdl)
    3.56    {
    3.57      ULONG copy_size;
    3.58      
    3.59      ASSERT(pi->curr_mdl);
    3.60 -    KdPrint((__DRIVER_NAME "     B bytes_remaining = %d, pi->curr_mdl = %p\n", bytes_remaining, pi->curr_mdl));
    3.61 +    //KdPrint((__DRIVER_NAME "     B bytes_remaining = %d, pi->curr_mdl = %p\n", bytes_remaining, pi->curr_mdl));
    3.62      if (MmGetMdlByteCount(pi->curr_mdl))
    3.63      {
    3.64        PUCHAR src_addr;
    3.65        src_addr = MmGetSystemAddressForMdlSafe(pi->curr_mdl, NormalPagePriority);
    3.66        if (!src_addr)
    3.67        {
    3.68 -        FUNCTION_EXIT();
    3.69 +        //FUNCTION_EXIT();
    3.70          return FALSE;
    3.71        }
    3.72        copy_size = min(bytes_remaining, MmGetMdlByteCount(pi->curr_mdl) - pi->curr_mdl_offset);
    3.73 -      KdPrint((__DRIVER_NAME "     B copy_size = %d\n", copy_size));
    3.74 +      //KdPrint((__DRIVER_NAME "     B copy_size = %d\n", copy_size));
    3.75        memcpy(header + pi->header_length,
    3.76          src_addr + pi->curr_mdl_offset, copy_size);
    3.77        pi->curr_mdl_offset = (USHORT)(pi->curr_mdl_offset + copy_size);
    3.78 @@ -95,27 +95,27 @@ XenNet_BuildHeader(packet_info_t *pi, PU
    3.79      }
    3.80      if (pi->curr_mdl_offset == MmGetMdlByteCount(pi->curr_mdl))
    3.81      {
    3.82 -      NdisGetNextBuffer(pi->curr_mdl, &pi->curr_mdl);
    3.83 +      NdisGetNextMdl(pi->curr_mdl, &pi->curr_mdl);
    3.84        if (pi->curr_pb)
    3.85          pi->curr_pb = pi->curr_pb->next;
    3.86        pi->curr_mdl_offset = 0;
    3.87      }
    3.88    }
    3.89 -  KdPrint((__DRIVER_NAME "     C bytes_remaining = %d, pi->curr_mdl = %p\n", bytes_remaining, pi->curr_mdl));
    3.90 +  //KdPrint((__DRIVER_NAME "     C bytes_remaining = %d, pi->curr_mdl = %p\n", bytes_remaining, pi->curr_mdl));
    3.91    if (bytes_remaining)
    3.92    {
    3.93 -    KdPrint((__DRIVER_NAME "     bytes_remaining\n"));
    3.94 -    FUNCTION_EXIT();
    3.95 +    //KdPrint((__DRIVER_NAME "     bytes_remaining\n"));
    3.96 +    //FUNCTION_EXIT();
    3.97      return FALSE;
    3.98    }
    3.99 -  FUNCTION_EXIT();
   3.100 +  //FUNCTION_EXIT();
   3.101    return TRUE;
   3.102  }
   3.103  
   3.104  ULONG
   3.105  XenNet_ParsePacketHeader(packet_info_t *pi, PUCHAR alt_buffer, ULONG min_header_size)
   3.106  {
   3.107 -  FUNCTION_ENTER();
   3.108 +  //FUNCTION_ENTER();
   3.109  
   3.110    ASSERT(pi->first_mdl);
   3.111    
   3.112 @@ -133,14 +133,14 @@ XenNet_ParsePacketHeader(packet_info_t *
   3.113    
   3.114    if (!XenNet_BuildHeader(pi, NULL, (ULONG)XN_HDR_SIZE))
   3.115    {
   3.116 -    KdPrint((__DRIVER_NAME "     packet too small (Ethernet Header)\n"));
   3.117 +    //KdPrint((__DRIVER_NAME "     packet too small (Ethernet Header)\n"));
   3.118      return PARSE_TOO_SMALL;
   3.119    }
   3.120  
   3.121    switch (GET_NET_PUSHORT(&pi->header[12])) // L2 protocol field
   3.122    {
   3.123    case 0x0800: /* IPv4 */
   3.124 -    KdPrint((__DRIVER_NAME "     IP\n"));
   3.125 +    //KdPrint((__DRIVER_NAME "     IP\n"));
   3.126      if (pi->header_length < (ULONG)(XN_HDR_SIZE + 20))
   3.127      {
   3.128        if (!XenNet_BuildHeader(pi, NULL, (ULONG)(XN_HDR_SIZE + 20)))
   3.129 @@ -152,7 +152,7 @@ XenNet_ParsePacketHeader(packet_info_t *
   3.130      pi->ip_version = (pi->header[XN_HDR_SIZE + 0] & 0xF0) >> 4;
   3.131      if (pi->ip_version != 4)
   3.132      {
   3.133 -      KdPrint((__DRIVER_NAME "     ip_version = %d\n", pi->ip_version));
   3.134 +      //KdPrint((__DRIVER_NAME "     ip_version = %d\n", pi->ip_version));
   3.135        return PARSE_UNKNOWN_TYPE;
   3.136      }
   3.137      pi->ip4_header_length = (pi->header[XN_HDR_SIZE + 0] & 0x0F) << 2;
   3.138 @@ -160,17 +160,17 @@ XenNet_ParsePacketHeader(packet_info_t *
   3.139      {
   3.140        if (!XenNet_BuildHeader(pi, NULL, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20)))
   3.141        {
   3.142 -        KdPrint((__DRIVER_NAME "     packet too small (IP Header + IP Options + TCP Header)\n"));
   3.143 +        //KdPrint((__DRIVER_NAME "     packet too small (IP Header + IP Options + TCP Header)\n"));
   3.144          return PARSE_TOO_SMALL;
   3.145        }
   3.146      }
   3.147      break;
   3.148    case 0x86DD:  /* IPv6 */
   3.149 -    KdPrint((__DRIVER_NAME "     IPv6\n"));
   3.150 -    KdPrint((__DRIVER_NAME "     (not currently used)\n"));
   3.151 +    //KdPrint((__DRIVER_NAME "     IPv6\n"));
   3.152 +    //KdPrint((__DRIVER_NAME "     (not currently used)\n"));
   3.153      return PARSE_UNKNOWN_TYPE;
   3.154    default:
   3.155 -    KdPrint((__DRIVER_NAME "     Not IP (%04x)\n", GET_NET_PUSHORT(&pi->header[12])));
   3.156 +    //KdPrint((__DRIVER_NAME "     Not IP (%04x)\n", GET_NET_PUSHORT(&pi->header[12])));
   3.157      return PARSE_UNKNOWN_TYPE;
   3.158    }
   3.159    pi->ip_proto = pi->header[XN_HDR_SIZE + 9];
   3.160 @@ -180,7 +180,7 @@ XenNet_ParsePacketHeader(packet_info_t *
   3.161    case 17: // UDP
   3.162      break;
   3.163    default:
   3.164 -    KdPrint((__DRIVER_NAME "     Not TCP/UDP (%d)\n", pi->ip_proto));
   3.165 +    //KdPrint((__DRIVER_NAME "     Not TCP/UDP (%d)\n", pi->ip_proto));
   3.166      return PARSE_UNKNOWN_TYPE;
   3.167    }
   3.168    pi->ip4_length = GET_NET_PUSHORT(&pi->header[XN_HDR_SIZE + 2]);
   3.169 @@ -190,14 +190,14 @@ XenNet_ParsePacketHeader(packet_info_t *
   3.170    {
   3.171      if (!XenNet_BuildHeader(pi, NULL, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + pi->tcp_header_length)))
   3.172      {
   3.173 -      KdPrint((__DRIVER_NAME "     packet too small (IP Header + IP Options + TCP Header + TCP Options)\n"));
   3.174 +      //KdPrint((__DRIVER_NAME "     packet too small (IP Header + IP Options + TCP Header + TCP Options)\n"));
   3.175        return PARSE_TOO_SMALL;
   3.176      }
   3.177    }
   3.178 -  
   3.179 +
   3.180    if ((ULONG)XN_HDR_SIZE + pi->ip4_length > pi->total_length)
   3.181    {
   3.182 -    KdPrint((__DRIVER_NAME "     XN_HDR_SIZE + ip4_length (%d) > total_length (%d)\n", XN_HDR_SIZE + pi->ip4_length, pi->total_length));
   3.183 +    //KdPrint((__DRIVER_NAME "     XN_HDR_SIZE + ip4_length (%d) > total_length (%d)\n", XN_HDR_SIZE + pi->ip4_length, pi->total_length));
   3.184      return PARSE_UNKNOWN_TYPE;
   3.185    }
   3.186  
   3.187 @@ -208,9 +208,9 @@ XenNet_ParsePacketHeader(packet_info_t *
   3.188    if (pi->mss > 0 && pi->tcp_length > pi->mss)
   3.189      pi->split_required = TRUE;
   3.190  
   3.191 -  KdPrint((__DRIVER_NAME "     ip4_length = %d\n", pi->ip4_length));
   3.192 -  KdPrint((__DRIVER_NAME "     tcp_length = %d\n", pi->tcp_length));
   3.193 -  FUNCTION_EXIT();
   3.194 +  //KdPrint((__DRIVER_NAME "     ip4_length = %d\n", pi->ip4_length));
   3.195 +  //KdPrint((__DRIVER_NAME "     tcp_length = %d\n", pi->tcp_length));
   3.196 +  //FUNCTION_EXIT();
   3.197    
   3.198    return PARSE_OK;
   3.199  }
     4.1 --- a/xennet/xennet6_oid.c	Mon May 02 00:18:22 2011 +1000
     4.2 +++ b/xennet/xennet6_oid.c	Thu May 05 22:39:13 2011 +1000
     4.3 @@ -107,9 +107,6 @@ XenNet_QueryInformation(
     4.4      case OID_GEN_RECEIVE_BLOCK_SIZE:
     4.5        temp_data = PAGE_SIZE; //XN_MAX_PKT_SIZE;
     4.6        break;
     4.7 -    case OID_GEN_VENDOR_ID:
     4.8 -      temp_data = 0xFFFFFF; // Not guaranteed to be XENSOURCE_MAC_HDR;
     4.9 -      break;
    4.10      case OID_GEN_VENDOR_DESCRIPTION:
    4.11        data = vendor_desc;
    4.12        len = sizeof(vendor_desc);
    4.13 @@ -137,10 +134,6 @@ XenNet_QueryInformation(
    4.14        /* this is actually ignored for deserialised drivers like us */
    4.15        temp_data = 0; //XN_MAX_SEND_PKTS;
    4.16        break;
    4.17 -    case OID_GEN_RCV_OK:
    4.18 -      temp_data = xi->stat_rx_ok;
    4.19 -      HANDLE_STAT_RETURN;
    4.20 -      break;
    4.21      case OID_GEN_XMIT_ERROR:
    4.22        temp_data = xi->stat_tx_error;
    4.23        HANDLE_STAT_RETURN;
    4.24 @@ -290,12 +283,6 @@ XenNet_QueryInformation(
    4.25  
    4.26        used_temp_buffer = FALSE;
    4.27        break;
    4.28 -    case OID_IP4_OFFLOAD_STATS:
    4.29 -    case OID_IP6_OFFLOAD_STATS:
    4.30 -      /* these are called often so just ignore then quietly */
    4.31 -      status = NDIS_STATUS_NOT_SUPPORTED;
    4.32 -      break;
    4.33 -
    4.34      case OID_PNP_CAPABILITIES:
    4.35        KdPrint(("Get OID_PNP_CAPABILITIES\n"));
    4.36        len = sizeof(NDIS_PNP_CAPABILITIES);
    4.37 @@ -344,17 +331,26 @@ XenNet_QueryInformation(
    4.38        data = xi->multicast_list;
    4.39        len = xi->multicast_list_size * 6;
    4.40        break;
    4.41 -    case OID_GEN_XMIT_OK:
    4.42 -      temp_data = xi->stat_tx_ok;
    4.43 -      HANDLE_STAT_RETURN;
    4.44 +    case OID_GEN_VENDOR_ID:
    4.45 +      temp_data = 0xFFFFFF; // Not guaranteed to be XENSOURCE_MAC_HDR;
    4.46 +      break;
    4.47 +    case OID_TCP_CONNECTION_OFFLOAD_HARDWARE_CAPABILITIES:
    4.48 +      FUNCTION_MSG("Unhandled OID_TCP_CONNECTION_OFFLOAD_HARDWARE_CAPABILITIES\n");
    4.49 +      break;
    4.50 +    case OID_TCP_CONNECTION_OFFLOAD_CURRENT_CONFIG:
    4.51 +      FUNCTION_MSG("Unhandled OID_TCP_CONNECTION_OFFLOAD_HARDWARE_CAPABILITIES\n");
    4.52 +      break;
    4.53 +    case OID_TCP_OFFLOAD_CURRENT_CONFIG:
    4.54 +      FUNCTION_MSG("Unhandled OID_TCP_OFFLOAD_CURRENT_CONFIG\n");
    4.55        break;
    4.56      default:
    4.57 -      KdPrint(("Get Unknown OID 0x%x\n", Oid));
    4.58 +      FUNCTION_MSG("Unhandled get OID_%08x\n", Oid);
    4.59      /* silently fail these */
    4.60 -    case OID_GEN_MACHINE_NAME:
    4.61      case OID_GEN_SUPPORTED_GUIDS:
    4.62 +    case OID_IP4_OFFLOAD_STATS:
    4.63 +    case OID_IP6_OFFLOAD_STATS:
    4.64        status = NDIS_STATUS_NOT_SUPPORTED;
    4.65 -    break;
    4.66 +      break;
    4.67    }
    4.68  
    4.69    if (!NT_SUCCESS(status))
    4.70 @@ -382,7 +378,156 @@ XenNet_QueryInformation(
    4.71    return status;
    4.72  }
    4.73  
    4.74 -NDIS_STATUS
    4.75 +static NDIS_STATUS
    4.76 +XenNet_QueryStatistics(
    4.77 +  IN NDIS_HANDLE MiniportAdapterContext,
    4.78 +  IN NDIS_OID Oid,
    4.79 +  IN PVOID InformationBuffer,
    4.80 +  IN ULONG InformationBufferLength,
    4.81 +  OUT PUINT BytesWritten,
    4.82 +  OUT PUINT BytesNeeded)
    4.83 +{
    4.84 +  NDIS_STATUS status = NDIS_STATUS_SUCCESS;
    4.85 +  struct xennet_info *xi = MiniportAdapterContext;
    4.86 +  BOOLEAN used_temp_buffer = TRUE;
    4.87 +  UINT len = 4;
    4.88 +  ULONG64 temp_data;
    4.89 +  PVOID data = &temp_data;
    4.90 +  PNDIS_STATISTICS_INFO nsi;
    4.91 +  //PIP_OFFLOAD_STATS ios;
    4.92 +#if 0
    4.93 +  UCHAR vendor_desc[] = XN_VENDOR_DESC;
    4.94 +  PNDIS_TASK_OFFLOAD_HEADER ntoh;
    4.95 +  PNDIS_TASK_OFFLOAD nto;
    4.96 +  PNDIS_TASK_TCP_IP_CHECKSUM nttic;
    4.97 +  PNDIS_TASK_TCP_LARGE_SEND nttls;
    4.98 +  PNDIS_PNP_CAPABILITIES npc;
    4.99 +#endif
   4.100 +
   4.101 +  *BytesNeeded = 0;
   4.102 +  *BytesWritten = 0;
   4.103 +
   4.104 +// FUNCTION_ENTER()
   4.105 +
   4.106 +  switch(Oid)
   4.107 +  {
   4.108 +#if 0
   4.109 +    case OID_GEN_XMIT_ERROR:
   4.110 +      temp_data = xi->stat_tx_error;
   4.111 +      HANDLE_STAT_RETURN;
   4.112 +      break;
   4.113 +    case OID_GEN_RCV_ERROR:
   4.114 +      temp_data = xi->stat_rx_error;
   4.115 +      HANDLE_STAT_RETURN;
   4.116 +      break;
   4.117 +    case OID_GEN_RCV_NO_BUFFER:
   4.118 +      temp_data = xi->stat_rx_no_buffer;
   4.119 +      HANDLE_STAT_RETURN;
   4.120 +      break;
   4.121 +    case OID_802_3_PERMANENT_ADDRESS:
   4.122 +      data = xi->perm_mac_addr;
   4.123 +      len = ETH_ALEN;
   4.124 +      break;
   4.125 +    case OID_802_3_RCV_ERROR_ALIGNMENT:
   4.126 +    case OID_802_3_XMIT_ONE_COLLISION:
   4.127 +    case OID_802_3_XMIT_MORE_COLLISIONS:
   4.128 +      temp_data = 0;
   4.129 +      HANDLE_STAT_RETURN;
   4.130 +      break;
   4.131 +#endif
   4.132 +    case OID_GEN_STATISTICS:
   4.133 +      SET_LEN_AND_BREAK_IF_SHORT(sizeof(NDIS_STATISTICS_INFO));
   4.134 +      nsi = (PNDIS_STATISTICS_INFO)InformationBuffer;
   4.135 +      nsi->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
   4.136 +      nsi->Header.Revision = NDIS_STATISTICS_INFO_REVISION_1;
   4.137 +      nsi->Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1;
   4.138 +      nsi->SupportedStatistics = 0;
   4.139 +      break;    
   4.140 +    case OID_GEN_XMIT_OK:
   4.141 +      temp_data = xi->stat_tx_ok;
   4.142 +      HANDLE_STAT_RETURN;
   4.143 +      break;
   4.144 +    case OID_GEN_RCV_OK:
   4.145 +      temp_data = xi->stat_rx_ok;
   4.146 +      HANDLE_STAT_RETURN;
   4.147 +      break;
   4.148 +#if 0
   4.149 +    case OID_IP4_OFFLOAD_STATS:
   4.150 +#if 0
   4.151 +      SET_LEN_AND_BREAK_IF_SHORT(sizeof(IP_OFFLOAD_STATS));
   4.152 +      ios = (PIP_OFFLOAD_STATS)InformationBuffer;
   4.153 +      ios->InReceives = 0;
   4.154 +      ios->InOctets = 0;
   4.155 +      ios->InDelivers = 0;
   4.156 +      ios->OutRequests = 0;
   4.157 +      ios->OutOctets = 0;
   4.158 +      ios->InHeaderErrors = 0;
   4.159 +      ios->InTruncatedPackets = 0;
   4.160 +      ios->InDiscards = 0;
   4.161 +      ios->OutDiscards= 0;
   4.162 +      ios->OutNoRoutes = 0;
   4.163 +#endif
   4.164 +      status = NDIS_STATUS_NOT_SUPPORTED;
   4.165 +      break;
   4.166 +    case OID_IP6_OFFLOAD_STATS:
   4.167 +#if 0
   4.168 +      SET_LEN_AND_BREAK_IF_SHORT(sizeof(IP_OFFLOAD_STATS));
   4.169 +      ios = (PIP_OFFLOAD_STATS)InformationBuffer;
   4.170 +      ios->InReceives = 0;
   4.171 +      ios->InOctets = 0;
   4.172 +      ios->InDelivers = 0;
   4.173 +      ios->OutRequests = 0;
   4.174 +      ios->OutOctets = 0;
   4.175 +      ios->InHeaderErrors = 0;
   4.176 +      ios->InTruncatedPackets = 0;
   4.177 +      ios->InDiscards = 0;
   4.178 +      ios->OutDiscards= 0;
   4.179 +      ios->OutNoRoutes = 0;
   4.180 +#endif
   4.181 +      status = NDIS_STATUS_NOT_SUPPORTED;
   4.182 +      break;
   4.183 +#endif
   4.184 +    case OID_TCP_CONNECTION_OFFLOAD_HARDWARE_CAPABILITIES:
   4.185 +      FUNCTION_MSG("Unhandled statistic OID_TCP_CONNECTION_OFFLOAD_HARDWARE_CAPABILITIES\n");
   4.186 +      break;
   4.187 +    case OID_TCP_CONNECTION_OFFLOAD_CURRENT_CONFIG:
   4.188 +      FUNCTION_MSG("Unhandled statistic OID_TCP_CONNECTION_OFFLOAD_HARDWARE_CAPABILITIES\n");
   4.189 +      break;
   4.190 +    case OID_TCP_OFFLOAD_CURRENT_CONFIG:
   4.191 +      FUNCTION_MSG("Unhandled statistic OID_TCP_OFFLOAD_CURRENT_CONFIG\n");
   4.192 +      break;
   4.193 +    default:
   4.194 +      KdPrint(("Unhandled statistics OID_%08x\n", Oid));
   4.195 +      status = NDIS_STATUS_NOT_SUPPORTED;
   4.196 +      break;
   4.197 +  }
   4.198 +
   4.199 +  if (!NT_SUCCESS(status))
   4.200 +  {
   4.201 +    //FUNCTION_EXIT_STATUS(status);
   4.202 +    return status;
   4.203 +  }
   4.204 +
   4.205 +  if (len > InformationBufferLength)
   4.206 +  {
   4.207 +    *BytesNeeded = len;
   4.208 +    FUNCTION_MSG("(BUFFER_TOO_SHORT %d > %d)\n", len, InformationBufferLength);
   4.209 +    return NDIS_STATUS_BUFFER_TOO_SHORT;
   4.210 +  }
   4.211 +
   4.212 +  *BytesWritten = len;
   4.213 +  if (len && used_temp_buffer)
   4.214 +  {
   4.215 +    NdisMoveMemory((PUCHAR)InformationBuffer, data, len);
   4.216 +  }
   4.217 +
   4.218 +  //KdPrint(("Got OID 0x%x\n", Oid));
   4.219 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   4.220 +
   4.221 +  return status;
   4.222 +}
   4.223 +
   4.224 +static NDIS_STATUS
   4.225  XenNet_SetInformation(
   4.226    IN NDIS_HANDLE adapter_context,
   4.227    IN NDIS_OID Oid,
   4.228 @@ -397,6 +542,7 @@ XenNet_SetInformation(
   4.229    PULONG64 data = InformationBuffer;
   4.230    ULONG i;
   4.231    UCHAR *multicast_list;
   4.232 +  PNDIS_OFFLOAD_ENCAPSULATION noe;
   4.233  #if 0
   4.234    PNDIS_TASK_OFFLOAD_HEADER ntoh;
   4.235    PNDIS_TASK_OFFLOAD nto;
   4.236 @@ -762,12 +908,57 @@ XenNet_SetInformation(
   4.237        break;
   4.238      case OID_GEN_CURRENT_LOOKAHEAD:
   4.239        xi->current_lookahead = *(ULONG *)data;
   4.240 -      KdPrint(("Set OID_GEN_CURRENT_LOOKAHEAD %d (%p)\n", xi->current_lookahead, xi));
   4.241 +      FUNCTION_MSG("Set OID_GEN_CURRENT_LOOKAHEAD %d (%p)\n", xi->current_lookahead, xi);
   4.242 +      status = NDIS_STATUS_SUCCESS;
   4.243 +      break;
   4.244 +    case OID_OFFLOAD_ENCAPSULATION:
   4.245 +      /* mostly assume that NDIS vets the settings for us */
   4.246 +      noe = (PNDIS_OFFLOAD_ENCAPSULATION)InformationBuffer;
   4.247 +      FUNCTION_MSG("Set OID_OFFLOAD_ENCAPSULATION\n");
   4.248 +      if (noe->IPv4.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3)
   4.249 +      {
   4.250 +        status = NDIS_STATUS_NOT_SUPPORTED;
   4.251 +        FUNCTION_MSG("Unknown Encapsulation Type %d\n", noe->IPv4.EncapsulationType);
   4.252 +        break;
   4.253 +      }
   4.254 +        
   4.255 +      switch(noe->IPv4.Enabled)
   4.256 +      {
   4.257 +      case NDIS_OFFLOAD_SET_ON:
   4.258 +        FUNCTION_MSG(" IPv4.Enabled = NDIS_OFFLOAD_SET_ON\n");
   4.259 +        xi->current_csum_ipv4 = TRUE;
   4.260 +        xi->current_lso_ipv4 = TRUE;
   4.261 +        break;
   4.262 +      case NDIS_OFFLOAD_SET_OFF:
   4.263 +        FUNCTION_MSG(" IPv4.Enabled = NDIS_OFFLOAD_SET_OFF\n");
   4.264 +        xi->current_csum_ipv4 = FALSE;
   4.265 +        xi->current_lso_ipv4 = FALSE;
   4.266 +        break;
   4.267 +      case NDIS_OFFLOAD_SET_NO_CHANGE:
   4.268 +        FUNCTION_MSG(" IPv4.Enabled = NDIS_OFFLOAD_NO_CHANGE\n");
   4.269 +        break;
   4.270 +      }
   4.271 +      FUNCTION_MSG(" IPv4.HeaderSize = %d\n", noe->IPv4.HeaderSize);
   4.272 +      FUNCTION_MSG(" IPv6.EncapsulationType = %d\n", noe->IPv6.EncapsulationType);
   4.273 +      switch(noe->IPv6.Enabled)
   4.274 +      {
   4.275 +      case NDIS_OFFLOAD_SET_ON:
   4.276 +        FUNCTION_MSG(" IPv6.Enabled = NDIS_OFFLOAD_SET_ON (this is an error)\n");
   4.277 +        break;
   4.278 +      case NDIS_OFFLOAD_SET_OFF:
   4.279 +        FUNCTION_MSG(" IPv6.Enabled = NDIS_OFFLOAD_SET_OFF\n");
   4.280 +        break;
   4.281 +      case NDIS_OFFLOAD_SET_NO_CHANGE:
   4.282 +        FUNCTION_MSG(" IPv6.Enabled = NDIS_OFFLOAD_NO_CHANGE\n");
   4.283 +        break;
   4.284 +      }
   4.285 +      FUNCTION_MSG(" IPv6.HeaderSize = %d\n", noe->IPv6.HeaderSize);
   4.286        status = NDIS_STATUS_SUCCESS;
   4.287        break;
   4.288      default:
   4.289 -      KdPrint(("Set Unknown OID 0x%x\n", Oid));
   4.290 +      FUNCTION_MSG("Unhandled set OID_%08x\n", Oid);
   4.291      case OID_GEN_NETWORK_LAYER_ADDRESSES: /* this could tell us what IP addresses there are for us to send arps after a suspend/resume */
   4.292 +    case OID_GEN_MACHINE_NAME:
   4.293        status = NDIS_STATUS_NOT_SUPPORTED;
   4.294        break;
   4.295    }
   4.296 @@ -791,11 +982,11 @@ XenNet_OidRequest(NDIS_HANDLE adapter_co
   4.297  {
   4.298    NTSTATUS status;
   4.299    
   4.300 -  FUNCTION_ENTER();
   4.301 +  //FUNCTION_ENTER();
   4.302    switch(oid_request->RequestType)
   4.303    {
   4.304    case NdisRequestQueryInformation:
   4.305 -    FUNCTION_MSG("RequestType = NdisRequestQueryInformation\n");
   4.306 +    //FUNCTION_MSG("RequestType = NdisRequestQueryInformation\n");
   4.307      //FUNCTION_MSG("Oid = %08x\n", oid_request->DATA.QUERY_INFORMATION.Oid);
   4.308      status = XenNet_QueryInformation(adapter_context,
   4.309        oid_request->DATA.QUERY_INFORMATION.Oid,
   4.310 @@ -805,7 +996,7 @@ XenNet_OidRequest(NDIS_HANDLE adapter_co
   4.311        &oid_request->DATA.QUERY_INFORMATION.BytesNeeded);
   4.312      break;
   4.313    case NdisRequestSetInformation:
   4.314 -    FUNCTION_MSG("RequestType = NdisRequestSetInformation\n");
   4.315 +    //FUNCTION_MSG("RequestType = NdisRequestSetInformation\n");
   4.316      //FUNCTION_MSG("Oid = %08x\n", oid_request->DATA.SET_INFORMATION.Oid);
   4.317      status = XenNet_SetInformation(adapter_context,
   4.318        oid_request->DATA.SET_INFORMATION.Oid,
   4.319 @@ -815,9 +1006,9 @@ XenNet_OidRequest(NDIS_HANDLE adapter_co
   4.320        &oid_request->DATA.SET_INFORMATION.BytesNeeded);
   4.321      break;
   4.322    case NdisRequestQueryStatistics:
   4.323 -    FUNCTION_MSG("RequestType = NdisRequestQueryStatistics\n");
   4.324 +    //FUNCTION_MSG("RequestType = NdisRequestQueryStatistics\n");
   4.325      //FUNCTION_MSG("Oid = %08x\n", oid_request->DATA.METHOD_INFORMATION.Oid);
   4.326 -    status = XenNet_QueryInformation(adapter_context,
   4.327 +    status = XenNet_QueryStatistics(adapter_context,
   4.328        oid_request->DATA.QUERY_INFORMATION.Oid,
   4.329        oid_request->DATA.QUERY_INFORMATION.InformationBuffer,
   4.330        oid_request->DATA.QUERY_INFORMATION.InformationBufferLength,
   4.331 @@ -829,7 +1020,7 @@ XenNet_OidRequest(NDIS_HANDLE adapter_co
   4.332      status = NDIS_STATUS_NOT_SUPPORTED;
   4.333      break;
   4.334    }
   4.335 -  FUNCTION_EXIT();
   4.336 +  //FUNCTION_EXIT();
   4.337    return status;
   4.338  }
   4.339  
     5.1 --- a/xennet/xennet6_rx.c	Mon May 02 00:18:22 2011 +1000
     5.2 +++ b/xennet/xennet6_rx.c	Thu May 05 22:39:13 2011 +1000
     5.3 @@ -82,11 +82,55 @@ put_pb_on_freelist(struct xennet_info *x
     5.4    {
     5.5      //NdisAdjustBufferLength(pb->buffer, PAGE_SIZE);
     5.6      //NDIS_BUFFER_LINKAGE(pb->buffer) = NULL;
     5.7 +    pb->mdl->ByteCount = PAGE_SIZE;
     5.8 +    pb->mdl->Next = NULL;
     5.9      pb->next = NULL;
    5.10      stack_push(xi->rx_pb_stack, pb);
    5.11      InterlockedIncrement(&xi->rx_pb_free);
    5.12    }
    5.13  }
    5.14 +
    5.15 +static __inline shared_buffer_t *
    5.16 +get_hb_from_freelist(struct xennet_info *xi)
    5.17 +{
    5.18 +  shared_buffer_t *hb;
    5.19 +  PVOID ptr_ref;
    5.20 +
    5.21 +  if (stack_pop(xi->rx_hb_stack, &ptr_ref))
    5.22 +  {
    5.23 +    hb = ptr_ref;
    5.24 +    InterlockedDecrement(&xi->rx_hb_free);
    5.25 +    return hb;
    5.26 +  }
    5.27 +
    5.28 +  /* don't allocate a new one if we are shutting down */
    5.29 +  if (xi->shutting_down)
    5.30 +    return NULL;
    5.31 +    
    5.32 +  hb = NdisAllocateMemoryWithTagPriority(xi->adapter_handle, sizeof(shared_buffer_t) + MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH, XENNET_POOL_TAG, LowPoolPriority);
    5.33 +  if (!hb)
    5.34 +    return NULL;
    5.35 +  NdisZeroMemory(hb, sizeof(shared_buffer_t));
    5.36 +  hb->mdl = IoAllocateMdl(hb + 1, MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH, FALSE, FALSE, NULL);
    5.37 +  if (!hb->mdl)
    5.38 +  {
    5.39 +    NdisFreeMemory(hb, sizeof(shared_buffer_t) + MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH, 0);
    5.40 +    return NULL;
    5.41 +  }
    5.42 +  MmBuildMdlForNonPagedPool(hb->mdl);
    5.43 +  return hb;
    5.44 +}
    5.45 +
    5.46 +static __inline VOID
    5.47 +put_hb_on_freelist(struct xennet_info *xi, shared_buffer_t *hb)
    5.48 +{
    5.49 +  hb->mdl->ByteCount = sizeof(shared_buffer_t) + MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH;
    5.50 +  hb->mdl->Next = NULL;
    5.51 +  hb->next = NULL;
    5.52 +  stack_push(xi->rx_hb_stack, hb);
    5.53 +  InterlockedIncrement(&xi->rx_hb_free);
    5.54 +}
    5.55 +
    5.56  // Called at DISPATCH_LEVEL with rx lock held
    5.57  static NDIS_STATUS
    5.58  XenNet_FillRing(struct xennet_info *xi)
    5.59 @@ -98,13 +142,13 @@ XenNet_FillRing(struct xennet_info *xi)
    5.60    RING_IDX req_prod = xi->rx.req_prod_pvt;
    5.61    netif_rx_request_t *req;
    5.62  
    5.63 -  FUNCTION_ENTER();
    5.64 +  //FUNCTION_ENTER();
    5.65  
    5.66    batch_target = xi->rx_target - (req_prod - xi->rx.rsp_cons);
    5.67  
    5.68    if (batch_target < (xi->rx_target >> 2))
    5.69    {
    5.70 -    FUNCTION_EXIT();
    5.71 +    //FUNCTION_EXIT();
    5.72      return NDIS_STATUS_SUCCESS; /* only refill if we are less than 3/4 full already */
    5.73    }
    5.74  
    5.75 @@ -135,7 +179,7 @@ XenNet_FillRing(struct xennet_info *xi)
    5.76      xi->vectors.EvtChn_Notify(xi->vectors.context, xi->event_channel);
    5.77    }
    5.78  
    5.79 -  FUNCTION_EXIT();
    5.80 +  //FUNCTION_EXIT();
    5.81  
    5.82    return NDIS_STATUS_SUCCESS;
    5.83  }
    5.84 @@ -203,7 +247,7 @@ XenNet_MakePacket(struct xennet_info *xi
    5.85    ULONG header_extra;
    5.86    shared_buffer_t *header_buf;
    5.87  
    5.88 -  FUNCTION_ENTER();
    5.89 +  //FUNCTION_ENTER();
    5.90    
    5.91    ASSERT(!pi->split_required);
    5.92    nb = NdisAllocateNetBuffer(xi->rx_nb_pool, NULL, 0, 0);
    5.93 @@ -211,21 +255,19 @@ XenNet_MakePacket(struct xennet_info *xi
    5.94    {
    5.95      /* buffers will be freed in MakePackets */
    5.96      KdPrint((__DRIVER_NAME "     No free packets\n"));
    5.97 -    FUNCTION_EXIT();
    5.98 +    //FUNCTION_EXIT();
    5.99      return FALSE;
   5.100    }
   5.101  
   5.102 -  /* is all this allocation and setup good for performance? would it be better on a lock free list? */
   5.103 -  header_buf = NdisAllocateFromNPagedLookasideList(&xi->rx_lookaside_list);
   5.104 +  header_buf = get_hb_from_freelist(xi);
   5.105    if (!header_buf)
   5.106    {
   5.107      KdPrint((__DRIVER_NAME "     No free header buffers\n"));
   5.108      NdisFreeNetBuffer(nb);
   5.109 -    FUNCTION_EXIT();
   5.110 +    //FUNCTION_EXIT();
   5.111      return FALSE;
   5.112    }
   5.113    header_va = (PUCHAR)(header_buf + 1);
   5.114 -  NdisZeroMemory(header_buf, sizeof(shared_buffer_t));
   5.115    NdisMoveMemory(header_va, pi->header, pi->header_length);
   5.116    //KdPrint((__DRIVER_NAME "     header_length = %d, current_lookahead = %d\n", pi->header_length, xi->current_lookahead));
   5.117    //KdPrint((__DRIVER_NAME "     ip4_header_length = %d\n", pi->ip4_header_length));
   5.118 @@ -244,17 +286,8 @@ XenNet_MakePacket(struct xennet_info *xi
   5.119    }
   5.120    header_extra = pi->header_length - (MAX_ETH_HEADER_LENGTH + pi->ip4_header_length + pi->tcp_header_length);
   5.121    ASSERT(pi->header_length <= MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH);
   5.122 -  curr_mdl = IoAllocateMdl(header_va, pi->header_length, FALSE, FALSE, NULL);
   5.123 -  if (!curr_mdl)
   5.124 -  {
   5.125 -    KdPrint((__DRIVER_NAME "     No free header buffers\n"));
   5.126 -    NdisFreeToNPagedLookasideList(&xi->rx_lookaside_list, header_buf);
   5.127 -    NdisFreeNetBuffer(nb);
   5.128 -    FUNCTION_EXIT();
   5.129 -    return FALSE;
   5.130 -  }
   5.131 -  MmBuildMdlForNonPagedPool(curr_mdl);
   5.132 -  mdl_head = mdl_tail = curr_mdl;
   5.133 +  header_buf->mdl->ByteCount = pi->header_length;
   5.134 +  mdl_head = mdl_tail = curr_mdl = header_buf->mdl;
   5.135    NB_HEADER_BUF(nb) = header_buf;
   5.136    header_buf->next = pi->curr_pb;
   5.137    NET_BUFFER_FIRST_MDL(nb) = mdl_head;
   5.138 @@ -284,7 +317,7 @@ XenNet_MakePacket(struct xennet_info *xi
   5.139      out_remaining = pi->total_length - pi->header_length;
   5.140      ASSERT((LONG)out_remaining >= 0);
   5.141    }
   5.142 -  KdPrint((__DRIVER_NAME "     before loop - out_remaining = %d\n", out_remaining));
   5.143 +  //KdPrint((__DRIVER_NAME "     before loop - out_remaining = %d\n", out_remaining));
   5.144  
   5.145    while (out_remaining != 0)
   5.146    {
   5.147 @@ -292,14 +325,14 @@ XenNet_MakePacket(struct xennet_info *xi
   5.148      ULONG in_buffer_length;
   5.149      ULONG out_length;
   5.150      
   5.151 -    KdPrint((__DRIVER_NAME "     in loop - out_remaining = %d, curr_buffer = %p, curr_pb = %p\n", out_remaining, pi->curr_mdl, pi->curr_pb));
   5.152 +    //KdPrint((__DRIVER_NAME "     in loop - out_remaining = %d, curr_buffer = %p, curr_pb = %p\n", out_remaining, pi->curr_mdl, pi->curr_pb));
   5.153      if (!pi->curr_mdl || !pi->curr_pb)
   5.154      {
   5.155 -      KdPrint((__DRIVER_NAME "     out of buffers for packet\n"));
   5.156 -      KdPrint((__DRIVER_NAME "     out_remaining = %d, curr_buffer = %p, curr_pb = %p\n", out_remaining, pi->curr_mdl, pi->curr_pb));
   5.157 +      //KdPrint((__DRIVER_NAME "     out of buffers for packet\n"));
   5.158 +      //KdPrint((__DRIVER_NAME "     out_remaining = %d, curr_buffer = %p, curr_pb = %p\n", out_remaining, pi->curr_mdl, pi->curr_pb));
   5.159        // TODO: free some stuff or we'll leak
   5.160        /* unchain buffers then free packet */
   5.161 -      FUNCTION_EXIT();
   5.162 +      //FUNCTION_EXIT();
   5.163        return FALSE;
   5.164      }
   5.165  
   5.166 @@ -312,7 +345,7 @@ XenNet_MakePacket(struct xennet_info *xi
   5.167      IoBuildPartialMdl(pi->curr_mdl, curr_mdl, (PUCHAR)MmGetMdlVirtualAddress(pi->curr_mdl) + pi->curr_mdl_offset, out_length);
   5.168      mdl_tail->Next = curr_mdl;
   5.169      mdl_tail = curr_mdl;
   5.170 -    curr_mdl->Next = NULL;
   5.171 +    curr_mdl->Next = NULL; /* I think this might be redundant */
   5.172      NET_BUFFER_DATA_LENGTH(nb) += out_length;
   5.173      ref_pb(xi, pi->curr_pb);
   5.174      pi->curr_mdl_offset = (USHORT)(pi->curr_mdl_offset + out_length);
   5.175 @@ -343,7 +376,7 @@ XenNet_MakePacket(struct xennet_info *xi
   5.176    }
   5.177    NBL_LAST_NB(nbl) = nb;
   5.178    NET_BUFFER_NEXT_NB(nb) = NULL; /*is this already done for me? */
   5.179 -  FUNCTION_EXIT();
   5.180 +  //FUNCTION_EXIT();
   5.181    return TRUE;
   5.182  }
   5.183  
   5.184 @@ -488,110 +521,100 @@ XenNet_MakePackets(struct xennet_info *x
   5.185  {
   5.186    PNET_BUFFER_LIST nbl = NULL;
   5.187    //UCHAR psh;
   5.188 -  //PNDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
   5.189 +  NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csum_info;
   5.190    ULONG parse_result;  
   5.191    //PNDIS_BUFFER buffer;
   5.192    shared_buffer_t *page_buf;
   5.193  
   5.194 -  FUNCTION_ENTER();
   5.195 +  //FUNCTION_ENTER();
   5.196  
   5.197    parse_result = XenNet_ParsePacketHeader(pi, NULL, 0);
   5.198 -KdPrint((__DRIVER_NAME "     A\n"));
   5.199  
   5.200    if (!XenNet_FilterAcceptPacket(xi, pi))
   5.201    {
   5.202 -KdPrint((__DRIVER_NAME "     B\n"));
   5.203      goto done;
   5.204    }
   5.205 -KdPrint((__DRIVER_NAME "     C\n"));
   5.206  
   5.207    nbl = NdisAllocateNetBufferList(xi->rx_nbl_pool, 0, 0);
   5.208 -KdPrint((__DRIVER_NAME "     D\n"));
   5.209    NBL_PACKET_COUNT(nbl) = 0;
   5.210 -KdPrint((__DRIVER_NAME "     E\n"));
   5.211  
   5.212    switch (pi->ip_proto)
   5.213    {
   5.214    case 6:  // TCP
   5.215 -KdPrint((__DRIVER_NAME "     F\n"));
   5.216      if (pi->split_required)
   5.217        break;
   5.218      // fallthrough
   5.219    case 17:  // UDP
   5.220 -KdPrint((__DRIVER_NAME "     G\n"));
   5.221      if (!XenNet_MakePacket(xi, nbl, pi))
   5.222      {
   5.223        KdPrint((__DRIVER_NAME "     Ran out of packets\n"));
   5.224        xi->stat_rx_no_buffer++;
   5.225        goto done;
   5.226      }
   5.227 -KdPrint((__DRIVER_NAME "     H\n"));
   5.228      if (parse_result == PARSE_OK)
   5.229      {
   5.230 -KdPrint((__DRIVER_NAME "     I\n"));
   5.231 -#if 0
   5.232        BOOLEAN checksum_offload = FALSE;
   5.233 -      csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
   5.234 -        packet, TcpIpChecksumPacketInfo);
   5.235 -      ASSERT(csum_info->Value == 0);
   5.236 +      csum_info.Value = 0;
   5.237        if (pi->csum_blank || pi->data_validated)
   5.238        {
   5.239 -        if (xi->setting_csum.V4Receive.TcpChecksum && pi->ip_proto == 6)
   5.240 +        if (pi->ip_proto == 6) // && xi->setting_csum.V4Receive.TcpChecksum)
   5.241          {
   5.242 -          if (!pi->tcp_has_options || xi->setting_csum.V4Receive.TcpOptionsSupported)
   5.243 -          {
   5.244 -            csum_info->Receive.NdisPacketIpChecksumSucceeded = TRUE;
   5.245 -            csum_info->Receive.NdisPacketTcpChecksumSucceeded = TRUE;
   5.246 +//          if (!pi->tcp_has_options || xi->setting_csum.V4Receive.TcpOptionsSupported)
   5.247 +//          {
   5.248 +            csum_info.Receive.IpChecksumSucceeded = TRUE;
   5.249 +            csum_info.Receive.TcpChecksumSucceeded = TRUE;
   5.250              checksum_offload = TRUE;
   5.251 -          }
   5.252 +//          }
   5.253          }
   5.254 -        else if (xi->setting_csum.V4Receive.UdpChecksum && pi->ip_proto == 17)
   5.255 +        else if (pi->ip_proto == 17) // &&xi->setting_csum.V4Receive.UdpChecksum)
   5.256          {
   5.257 -          csum_info->Receive.NdisPacketIpChecksumSucceeded = TRUE;
   5.258 -          csum_info->Receive.NdisPacketUdpChecksumSucceeded = TRUE;
   5.259 +          csum_info.Receive.IpChecksumSucceeded = TRUE;
   5.260 +          csum_info.Receive.UdpChecksumSucceeded = TRUE;
   5.261            checksum_offload = TRUE;
   5.262          }
   5.263 +#if 0
   5.264          if (pi->csum_blank && (!xi->config_csum_rx_dont_fix || !checksum_offload))
   5.265          {
   5.266            XenNet_SumPacketData(pi, packet, TRUE);
   5.267          }
   5.268 +#endif
   5.269        }
   5.270 +#if 0
   5.271        else if (xi->config_csum_rx_check)
   5.272        {
   5.273          if (xi->setting_csum.V4Receive.TcpChecksum && pi->ip_proto == 6)
   5.274          {
   5.275            if (XenNet_SumPacketData(pi, packet, FALSE))
   5.276            {
   5.277 -            csum_info->Receive.NdisPacketTcpChecksumSucceeded = TRUE;
   5.278 +            csum_info.Receive.NdisPacketTcpChecksumSucceeded = TRUE;
   5.279            }
   5.280            else
   5.281            {
   5.282 -            csum_info->Receive.NdisPacketTcpChecksumFailed = TRUE;
   5.283 +            csum_info.Receive.NdisPacketTcpChecksumFailed = TRUE;
   5.284            }
   5.285          } else if (xi->setting_csum.V4Receive.UdpChecksum && pi->ip_proto == 17)
   5.286          {
   5.287            if (XenNet_SumPacketData(pi, packet, FALSE))
   5.288            {
   5.289 -            csum_info->Receive.NdisPacketUdpChecksumSucceeded = TRUE;
   5.290 +            csum_info.Receive.NdisPacketUdpChecksumSucceeded = TRUE;
   5.291            }
   5.292            else
   5.293            {
   5.294 -            csum_info->Receive.NdisPacketUdpChecksumFailed = TRUE;
   5.295 +            csum_info.Receive.NdisPacketUdpChecksumFailed = TRUE;
   5.296            }
   5.297          }
   5.298        }
   5.299  #endif
   5.300 +      NET_BUFFER_LIST_INFO(nbl, TcpIpChecksumNetBufferListInfo) = csum_info.Value;
   5.301      }
   5.302      goto done;
   5.303    default:
   5.304 -KdPrint((__DRIVER_NAME "     J\n"));
   5.305      if (!XenNet_MakePacket(xi, nbl, pi))
   5.306      {
   5.307        KdPrint((__DRIVER_NAME "     Ran out of packets\n"));
   5.308        xi->stat_rx_no_buffer++;
   5.309        goto done;
   5.310      }
   5.311 -KdPrint((__DRIVER_NAME "     K\n"));
   5.312      goto done;
   5.313    }
   5.314    KdPrint((__DRIVER_NAME "     What are we doing here???\n"));
   5.315 @@ -648,7 +671,7 @@ done:
   5.316      page_buf = next_pb;
   5.317    }
   5.318    XenNet_ClearPacketInfo(pi);
   5.319 -  FUNCTION_EXIT();
   5.320 +  //FUNCTION_EXIT();
   5.321    return nbl;
   5.322  }
   5.323  
   5.324 @@ -660,7 +683,7 @@ XenNet_ReturnNetBufferLists(NDIS_HANDLE 
   5.325    struct xennet_info *xi = adapter_context;
   5.326    UNREFERENCED_PARAMETER(return_flags);
   5.327  
   5.328 -  FUNCTION_ENTER();
   5.329 +  //FUNCTION_ENTER();
   5.330  
   5.331    //KdPrint((__DRIVER_NAME "     page_buf = %p\n", page_buf));
   5.332  
   5.333 @@ -685,21 +708,20 @@ XenNet_ReturnNetBufferLists(NDIS_HANDLE 
   5.334          shared_buffer_t *next_buf;
   5.335          PMDL next_mdl;
   5.336          
   5.337 -        ASSERT(page_buf);
   5.338 +        ASSERT(page_buf); /* make sure that there is a pb to match this mdl */
   5.339          next_mdl = curr_mdl->Next;
   5.340          next_buf = page_buf->next;
   5.341          if (!page_buf->virtual)
   5.342          {
   5.343 -          /* this isn't actually a share_buffer, it is some memory allocated for the header - just free it */
   5.344 -          NdisFreeToNPagedLookasideList(&xi->rx_lookaside_list, (PUCHAR)MmGetMdlVirtualAddress(curr_mdl) - sizeof(shared_buffer_t));
   5.345 -          IoFreeMdl(curr_mdl);
   5.346 +          /* this is a hb not a pb because virtual is NULL (virtual is just the memory after the hb */
   5.347 +          put_hb_on_freelist(xi, (shared_buffer_t *)MmGetMdlVirtualAddress(curr_mdl) - 1);
   5.348          }
   5.349          else
   5.350          {
   5.351            //KdPrint((__DRIVER_NAME "     returning page_buf %p with id %d\n", page_buf, page_buf->id));
   5.352            if (curr_mdl != page_buf->mdl)
   5.353            {
   5.354 -            KdPrint((__DRIVER_NAME "     curr_mdl = %p, page_buf->mdl = %p\n", curr_mdl, page_buf->mdl));
   5.355 +            //KdPrint((__DRIVER_NAME "     curr_mdl = %p, page_buf->mdl = %p\n", curr_mdl, page_buf->mdl));
   5.356              IoFreeMdl(curr_mdl);
   5.357            }
   5.358            put_pb_on_freelist(xi, page_buf);
   5.359 @@ -720,7 +742,7 @@ XenNet_ReturnNetBufferLists(NDIS_HANDLE 
   5.360    if (!xi->rx_outstanding && xi->rx_shutting_down)
   5.361      KeSetEvent(&xi->packet_returned_event, IO_NO_INCREMENT, FALSE);
   5.362  
   5.363 -  FUNCTION_EXIT();
   5.364 +  //FUNCTION_EXIT();
   5.365  }
   5.366  
   5.367  #define MAXIMUM_PACKETS_PER_INDICATE 32
   5.368 @@ -757,7 +779,7 @@ XenNet_RxBufferCheck(struct xennet_info 
   5.369    BOOLEAN more_data_flag = FALSE;
   5.370    BOOLEAN dont_set_event;
   5.371  
   5.372 -  FUNCTION_ENTER();
   5.373 +  //FUNCTION_ENTER();
   5.374  
   5.375    if (!xi->connected)
   5.376      return FALSE; /* a delayed DPC could let this come through... just do nothing */
   5.377 @@ -798,7 +820,6 @@ XenNet_RxBufferCheck(struct xennet_info 
   5.378        xi->rx_ring_pbs[id] = NULL;
   5.379        xi->rx_id_free++;
   5.380        memcpy(&page_buf->rsp, RING_GET_RESPONSE(&xi->rx, cons), max(sizeof(struct netif_rx_response), sizeof(struct netif_extra_info)));
   5.381 -KdPrint((__DRIVER_NAME "     got buffer from ring\n"));
   5.382        if (!extra_info_flag)
   5.383        {
   5.384          if (page_buf->rsp.status <= 0
   5.385 @@ -934,12 +955,10 @@ KdPrint((__DRIVER_NAME "     got buffer 
   5.386        ASSERT(!page_buf->rsp.offset);
   5.387        if (!more_data_flag) // handling the packet's 1st buffer
   5.388        {
   5.389 -#if 0
   5.390          if (page_buf->rsp.flags & NETRXF_csum_blank)
   5.391            pi->csum_blank = TRUE;
   5.392          if (page_buf->rsp.flags & NETRXF_data_validated)
   5.393            pi->data_validated = TRUE;
   5.394 -#endif
   5.395        }
   5.396        mdl = page_buf->mdl;
   5.397        mdl->ByteCount = page_buf->rsp.status; //NdisAdjustBufferLength(mdl, page_buf->rsp.status);
   5.398 @@ -974,39 +993,32 @@ KdPrint((__DRIVER_NAME "     got buffer 
   5.399        pi->curr_pb = pi->first_pb;
   5.400        pi->curr_mdl = pi->first_mdl;
   5.401        nbl = XenNet_MakePackets(xi, pi);
   5.402 -KdPrint((__DRIVER_NAME "     A\n"));
   5.403        if (nbl)
   5.404        {
   5.405 -KdPrint((__DRIVER_NAME "     B\n"));
   5.406          packet_count += NBL_PACKET_COUNT(nbl);
   5.407 -KdPrint((__DRIVER_NAME "     C %d\n", packet_count));
   5.408          nbl_count++;
   5.409          if (!nbl_head)
   5.410          {
   5.411 -KdPrint((__DRIVER_NAME "     D\n"));
   5.412            nbl_head = nbl;
   5.413            nbl_tail = nbl;
   5.414          }
   5.415          else
   5.416          {
   5.417 -KdPrint((__DRIVER_NAME "     E\n"));
   5.418            NET_BUFFER_LIST_NEXT_NBL(nbl_tail) = nbl;
   5.419          }
   5.420          NET_BUFFER_LIST_NEXT_NBL(nbl) = NULL;
   5.421 -KdPrint((__DRIVER_NAME "     F\n"));
   5.422        }
   5.423 -KdPrint((__DRIVER_NAME "     G\n"));
   5.424      }
   5.425  
   5.426      page_buf = next_buf;
   5.427    }
   5.428 -KdPrint((__DRIVER_NAME "     H\n"));
   5.429    ASSERT(!more_data_flag && !extra_info_flag);
   5.430  
   5.431    xi->stat_rx_ok += packet_count;
   5.432  
   5.433    if (nbl_head)
   5.434    {
   5.435 +#if 0
   5.436  KdPrint((__DRIVER_NAME "     I %d %p\n", nbl_count, nbl_head));
   5.437  KdPrint((__DRIVER_NAME "     nbl_head->Context = %p\n", nbl_head->Context));
   5.438  KdPrint((__DRIVER_NAME "     nbl_head->ParentNetBufferList = %p\n", nbl_head->ParentNetBufferList));
   5.439 @@ -1019,13 +1031,13 @@ KdPrint((__DRIVER_NAME "     nbl_head->C
   5.440  KdPrint((__DRIVER_NAME "     NET_BUFFER_LIST_FIRST_NB(nbl_head) = %p\n", NET_BUFFER_LIST_FIRST_NB(nbl_head)));
   5.441  KdPrint((__DRIVER_NAME "     NET_BUFFER_FIRST_MDL(nb) = %p\n", NET_BUFFER_FIRST_MDL(NET_BUFFER_LIST_FIRST_NB((nbl_head)))));
   5.442  KdPrint((__DRIVER_NAME "     NET_BUFFER_FIRST_MDL(nb)->Next = %p\n", NET_BUFFER_FIRST_MDL(NET_BUFFER_LIST_FIRST_NB((nbl_head)))->Next));
   5.443 +#endif
   5.444  
   5.445      NdisMIndicateReceiveNetBufferLists(xi->adapter_handle, nbl_head, NDIS_DEFAULT_PORT_NUMBER, nbl_count,
   5.446        NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL
   5.447        | NDIS_RECEIVE_FLAGS_SINGLE_ETHER_TYPE 
   5.448        | NDIS_RECEIVE_FLAGS_PERFECT_FILTERED);
   5.449    };
   5.450 -KdPrint((__DRIVER_NAME "     J\n"));
   5.451  #if 0
   5.452    /* indicate packets to NDIS */
   5.453    entry = RemoveHeadList(&rx_packet_list);
   5.454 @@ -1060,7 +1072,7 @@ KdPrint((__DRIVER_NAME "     J\n"));
   5.455      XenNet_ReturnPacket(xi, packet);
   5.456    }
   5.457  #endif
   5.458 -  FUNCTION_EXIT();
   5.459 +  //FUNCTION_EXIT();
   5.460    return dont_set_event;
   5.461  }
   5.462  
   5.463 @@ -1086,18 +1098,23 @@ XenNet_PurgeRing(struct xennet_info *xi)
   5.464  static VOID
   5.465  XenNet_BufferFree(struct xennet_info *xi)
   5.466  {
   5.467 -  shared_buffer_t *pb;
   5.468 +  shared_buffer_t *sb;
   5.469  
   5.470    XenNet_PurgeRing(xi);
   5.471  
   5.472    /* because we are shutting down this won't allocate new ones */
   5.473 -  while ((pb = get_pb_from_freelist(xi)) != NULL)
   5.474 +  while ((sb = get_pb_from_freelist(xi)) != NULL)
   5.475    {
   5.476      xi->vectors.GntTbl_EndAccess(xi->vectors.context,
   5.477 -        pb->gref, FALSE, (ULONG)'XNRX');
   5.478 -    IoFreeMdl(pb->mdl);
   5.479 -    NdisFreeMemory(pb, PAGE_SIZE, 0);
   5.480 -    NdisFreeMemory(pb->virtual, sizeof(shared_buffer_t), 0);
   5.481 +        sb->gref, FALSE, (ULONG)'XNRX');
   5.482 +    IoFreeMdl(sb->mdl);
   5.483 +    NdisFreeMemory(sb, PAGE_SIZE, 0);
   5.484 +    NdisFreeMemory(sb->virtual, sizeof(shared_buffer_t), 0);
   5.485 +  }
   5.486 +  while ((sb = get_hb_from_freelist(xi)) != NULL)
   5.487 +  {
   5.488 +    IoFreeMdl(sb->mdl);
   5.489 +    NdisFreeMemory(sb->virtual, sizeof(shared_buffer_t) + MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH, 0);
   5.490    }
   5.491  }
   5.492  
   5.493 @@ -1167,6 +1184,7 @@ XenNet_RxInit(xennet_info_t *xi)
   5.494    NdisZeroMemory(xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount());
   5.495  
   5.496    stack_new(&xi->rx_pb_stack, NET_RX_RING_SIZE * 4);
   5.497 +  stack_new(&xi->rx_hb_stack, NET_RX_RING_SIZE * 4);
   5.498  
   5.499    XenNet_BufferAlloc(xi);
   5.500    
   5.501 @@ -1199,9 +1217,6 @@ XenNet_RxInit(xennet_info_t *xi)
   5.502      return FALSE;
   5.503    }
   5.504  
   5.505 -  NdisInitializeNPagedLookasideList(&xi->rx_lookaside_list, NULL, NULL, 0,
   5.506 -    MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH + sizeof(shared_buffer_t), XENNET_POOL_TAG, 0);
   5.507 -  
   5.508    XenNet_FillRing(xi);
   5.509  
   5.510    FUNCTION_EXIT();
   5.511 @@ -1248,9 +1263,8 @@ XenNet_RxShutdown(xennet_info_t *xi)
   5.512    //stack_delete(xi->rx_packet_stack, NULL, NULL);
   5.513    NdisFreePacketPool(xi->rx_packet_pool);
   5.514  
   5.515 -  NdisDeleteNPagedLookasideList(&xi->rx_lookaside_list);
   5.516 -
   5.517    stack_delete(xi->rx_pb_stack, NULL, NULL);
   5.518 +  stack_delete(xi->rx_hb_stack, NULL, NULL);
   5.519    //KeReleaseSpinLock(&xi->rx_lock, old_irql);
   5.520  
   5.521  #endif
     6.1 --- a/xennet/xennet6_tx.c	Mon May 02 00:18:22 2011 +1000
     6.2 +++ b/xennet/xennet6_tx.c	Thu May 05 22:39:13 2011 +1000
     6.3 @@ -68,8 +68,9 @@ XenNet_HWSendPacket(struct xennet_info *
     6.4    struct netif_tx_request *tx0 = NULL;
     6.5    struct netif_tx_request *txN = NULL;
     6.6    struct netif_extra_info *ei = NULL;
     6.7 -  //PNDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
     6.8 +  NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO lso_info;
     6.9    ULONG mss = 0;
    6.10 +  NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csum_info;
    6.11    uint16_t flags = NETTXF_more_data;
    6.12    packet_info_t pi;
    6.13    BOOLEAN ndis_lso = FALSE;
    6.14 @@ -83,7 +84,7 @@ XenNet_HWSendPacket(struct xennet_info *
    6.15    grant_ref_t gref;
    6.16    ULONG tx_length = 0;
    6.17    
    6.18 -  FUNCTION_ENTER();
    6.19 +  //FUNCTION_ENTER();
    6.20  
    6.21    gref = xi->vectors.GntTbl_GetRef(xi->vectors.context, (ULONG)'XNTX');
    6.22    if (gref == INVALID_GRANT_REF)
    6.23 @@ -100,43 +101,39 @@ XenNet_HWSendPacket(struct xennet_info *
    6.24    }
    6.25    XenNet_ClearPacketInfo(&pi);
    6.26    //NdisQueryPacket(packet, NULL, (PUINT)&pi.mdl_count, &pi.first_buffer, (PUINT)&pi.total_length);
    6.27 -  pi.first_mdl = pi.curr_mdl = nb->CurrentMdl;
    6.28 -  pi.first_mdl_offset = pi.curr_mdl_offset = nb->CurrentMdlOffset;
    6.29 +  /* create a new MDL over the data portion of the first MDL in the packet... it's just easier this way */
    6.30 +  IoBuildPartialMdl(nb->CurrentMdl,
    6.31 +    &pi.first_mdl_storage,
    6.32 +    (PUCHAR)MmGetMdlVirtualAddress(nb->CurrentMdl) + nb->CurrentMdlOffset,
    6.33 +    MmGetMdlByteCount(nb->CurrentMdl) - nb->CurrentMdlOffset);
    6.34 +  pi.first_mdl_storage.Next = nb->CurrentMdl->Next;
    6.35 +  pi.first_mdl = pi.curr_mdl = &pi.first_mdl_storage;
    6.36 +  pi.first_mdl_offset = pi.curr_mdl_offset = 0;
    6.37    pi.total_length = nb->DataLength;
    6.38 -//KdPrint((__DRIVER_NAME "     A first_mdl = %p\n", pi.first_mdl));
    6.39 -KdPrint((__DRIVER_NAME "     A total_length = %d\n", pi.total_length));
    6.40 -KdPrint((__DRIVER_NAME "     B curr_mdl_offset = %p\n", pi.curr_mdl_offset));
    6.41    remaining = min(pi.total_length, PAGE_SIZE);
    6.42 -KdPrint((__DRIVER_NAME "     C remaining = %d\n", remaining));
    6.43    while (remaining) /* this much gets put in the header */
    6.44    {
    6.45      ULONG length = XenNet_QueryData(&pi, remaining);
    6.46      remaining -= length;
    6.47 -KdPrint((__DRIVER_NAME "     D length = %d, remaining = %d\n", length, remaining));
    6.48      XenNet_EatData(&pi, length);
    6.49    }
    6.50    frags++;
    6.51 -KdPrint((__DRIVER_NAME "     Da\n"));
    6.52    if (pi.total_length > PAGE_SIZE) /* these are the frags we care about */
    6.53    {
    6.54      remaining = pi.total_length - PAGE_SIZE;
    6.55 -KdPrint((__DRIVER_NAME "     E remaining = %d\n", remaining));
    6.56      while (remaining)
    6.57      {
    6.58        ULONG length = XenNet_QueryData(&pi, PAGE_SIZE);
    6.59 -KdPrint((__DRIVER_NAME "     F length = %d\n", length));
    6.60        if (length != 0)
    6.61        {
    6.62          frags++;
    6.63          if (frags > LINUX_MAX_SG_ELEMENTS)
    6.64            break; /* worst case there could be hundreds of fragments - leave the loop now */
    6.65        }
    6.66 -KdPrint((__DRIVER_NAME "     G remaining = %d\n", remaining));
    6.67        remaining -= length;
    6.68        XenNet_EatData(&pi, length);
    6.69      }
    6.70    }
    6.71 -KdPrint((__DRIVER_NAME "     H remaining = %d, frags = %d, LINUX_MAX_SG_ELEMENTS = %d\n", remaining, frags, LINUX_MAX_SG_ELEMENTS));
    6.72    if (frags > LINUX_MAX_SG_ELEMENTS)
    6.73    {
    6.74      frags = LINUX_MAX_SG_ELEMENTS;
    6.75 @@ -152,74 +149,105 @@ KdPrint((__DRIVER_NAME "     H remaining
    6.76      return FALSE;
    6.77    }
    6.78    parse_result = XenNet_ParsePacketHeader(&pi, coalesce_buf, PAGE_SIZE);
    6.79 -KdPrint((__DRIVER_NAME "     I parse_result = %d\n", parse_result));
    6.80    remaining = pi.total_length - pi.header_length;
    6.81 -KdPrint((__DRIVER_NAME "     J total_length = %d, header_length = %d, remaining = %d\n", pi.total_length, pi.header_length, remaining));
    6.82 -
    6.83 -#if 0
    6.84 -  if (NDIS_GET_PACKET_PROTOCOL_TYPE(packet) == NDIS_PROTOCOL_ID_TCP_IP)
    6.85 +  if (pi.ip_version == 4 && pi.ip_proto == 6 && pi.ip4_length == 0)
    6.86    {
    6.87 -    csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
    6.88 -      packet, TcpIpChecksumPacketInfo);
    6.89 -    if (csum_info->Transmit.NdisPacketChecksumV4)
    6.90 +#if 0  
    6.91 +    PMDL tmp_mdl;
    6.92 +    PUCHAR my_va;
    6.93 +    FUNCTION_MSG("total_length == 0, CurrentMdlOffset == %d\n", nb->CurrentMdlOffset);
    6.94 +    my_va = MmGetMdlVirtualAddress(pi.first_mdl);
    6.95 +    FUNCTION_MSG("  first mdl va = %p, offset = %d, length = %d\n", MmGetMdlVirtualAddress(pi.first_mdl), MmGetMdlByteOffset(pi.first_mdl), MmGetMdlByteCount(pi.first_mdl));      
    6.96 +    FUNCTION_MSG("    0010: %02x%02x\n", my_va[0x10], my_va[0x11]);
    6.97 +    for (tmp_mdl = nb->CurrentMdl; tmp_mdl; tmp_mdl = tmp_mdl->Next)
    6.98      {
    6.99 -      if (csum_info->Transmit.NdisPacketIpChecksum && !xi->setting_csum.V4Transmit.IpChecksum)
   6.100 +      FUNCTION_MSG("  mdl = %p, va = %p, offset = %d, length = %d\n", tmp_mdl, MmGetMdlVirtualAddress(tmp_mdl), MmGetMdlByteOffset(tmp_mdl), MmGetMdlByteCount(tmp_mdl));      
   6.101 +      if (tmp_mdl == nb->CurrentMdl)
   6.102        {
   6.103 -        KdPrint((__DRIVER_NAME "     IpChecksum not enabled\n"));
   6.104 +        my_va = MmGetSystemAddressForMdlSafe(tmp_mdl, HighPagePriority);
   6.105 +        my_va += nb->CurrentMdlOffset;
   6.106 +        FUNCTION_MSG("    0010: %02x%02x\n", my_va[0x10], my_va[0x11]);
   6.107 +      }
   6.108 +    }
   6.109 +#endif
   6.110 +    *((PUSHORT)(pi.header + 0x10)) = GET_NET_USHORT((USHORT)nb->DataLength - XN_HDR_SIZE);
   6.111 +  }
   6.112 +
   6.113 +  // do we need to check if the packet is tcpip??
   6.114 +  csum_info.Value = NET_BUFFER_LIST_INFO(NB_NBL(nb), TcpIpChecksumNetBufferListInfo);
   6.115 +  if (csum_info.Transmit.IsIPv4)
   6.116 +  {
   6.117 +#if 0
   6.118 +    if (csum_info.Transmit.IpHeaderChecksum && !xi->setting_csum.V4Transmit.IpChecksum)
   6.119 +    {
   6.120 +      KdPrint((__DRIVER_NAME "     IpChecksum not enabled\n"));
   6.121 +      //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
   6.122 +      //return TRUE;
   6.123 +    }
   6.124 +#endif
   6.125 +    if (csum_info.Transmit.TcpChecksum)
   6.126 +    {
   6.127 +      if (1) //xi->setting_csum.V4Transmit.TcpChecksum)
   6.128 +      {
   6.129 +        flags |= NETTXF_csum_blank | NETTXF_data_validated;
   6.130 +      }
   6.131 +      else
   6.132 +      {
   6.133 +        KdPrint((__DRIVER_NAME "     TcpChecksum not enabled\n"));
   6.134          //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
   6.135          //return TRUE;
   6.136        }
   6.137 -      if (csum_info->Transmit.NdisPacketTcpChecksum)
   6.138 +    }
   6.139 +    else if (csum_info.Transmit.UdpChecksum)
   6.140 +    {
   6.141 +      if (1) //xi->setting_csum.V4Transmit.UdpChecksum)
   6.142        {
   6.143 -        if (xi->setting_csum.V4Transmit.TcpChecksum)
   6.144 -        {
   6.145 -          flags |= NETTXF_csum_blank | NETTXF_data_validated;
   6.146 -        }
   6.147 -        else
   6.148 -        {
   6.149 -          KdPrint((__DRIVER_NAME "     TcpChecksum not enabled\n"));
   6.150 -          //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
   6.151 -          //return TRUE;
   6.152 -        }
   6.153 +        flags |= NETTXF_csum_blank | NETTXF_data_validated;
   6.154        }
   6.155 -      else if (csum_info->Transmit.NdisPacketUdpChecksum)
   6.156 +      else
   6.157        {
   6.158 -        if (xi->setting_csum.V4Transmit.UdpChecksum)
   6.159 -        {
   6.160 -          flags |= NETTXF_csum_blank | NETTXF_data_validated;
   6.161 -        }
   6.162 -        else
   6.163 -        {
   6.164 -          KdPrint((__DRIVER_NAME "     UdpChecksum not enabled\n"));
   6.165 -          //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
   6.166 -          //return TRUE;
   6.167 -        }
   6.168 +        KdPrint((__DRIVER_NAME "     UdpChecksum not enabled\n"));
   6.169 +        //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
   6.170 +        //return TRUE;
   6.171        }
   6.172      }
   6.173 -    else if (csum_info->Transmit.NdisPacketChecksumV6)
   6.174 -    {
   6.175 -      KdPrint((__DRIVER_NAME "     NdisPacketChecksumV6 not supported\n"));
   6.176 -      //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
   6.177 -      //return TRUE;
   6.178 -    }
   6.179 +  }
   6.180 +  else if (csum_info.Transmit.IsIPv6)
   6.181 +  {
   6.182 +    KdPrint((__DRIVER_NAME "     Transmit.IsIPv6 not supported\n"));
   6.183 +    //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
   6.184 +    //return TRUE;
   6.185    }
   6.186    
   6.187 -  mss = PtrToUlong(NDIS_PER_PACKET_INFO_FROM_PACKET(packet, TcpLargeSendPacketInfo));
   6.188 -
   6.189 +  lso_info.Value = NET_BUFFER_LIST_INFO(NB_NBL(nb), TcpLargeSendNetBufferListInfo);
   6.190 +  switch (lso_info.Transmit.Type)
   6.191 +  {
   6.192 +  case NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE:
   6.193 +    mss = lso_info.LsoV1Transmit.MSS;
   6.194 +    /* should make use of TcpHeaderOffset too... maybe just assert if it's not what we expect */
   6.195 +    break;
   6.196 +  case NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE:
   6.197 +    mss = lso_info.LsoV2Transmit.MSS;
   6.198 +    /* should make use of TcpHeaderOffset too... maybe just assert if it's not what we expect */
   6.199 +    break;
   6.200 +  }
   6.201    if (mss && parse_result == PARSE_OK)
   6.202    {
   6.203 -    if (NDIS_GET_PACKET_PROTOCOL_TYPE(packet) != NDIS_PROTOCOL_ID_TCP_IP)
   6.204 +    //FUNCTION_MSG("lso mss = %d\n", mss);
   6.205 +    //if (NDIS_GET_PACKET_PROTOCOL_TYPE(packet) != NDIS_PROTOCOL_ID_TCP_IP)
   6.206 +    //{
   6.207 +    //  KdPrint((__DRIVER_NAME "     mss specified when packet is not NDIS_PROTOCOL_ID_TCP_IP\n"));
   6.208 +    //}
   6.209 +    ndis_lso = TRUE;
   6.210 +    #if 0
   6.211 +    if (mss > xi->current_lso_ipv4)
   6.212      {
   6.213 -      KdPrint((__DRIVER_NAME "     mss specified when packet is not NDIS_PROTOCOL_ID_TCP_IP\n"));
   6.214 -    }
   6.215 -    ndis_lso = TRUE;
   6.216 -    if (mss > xi->setting_max_offload)
   6.217 -    {
   6.218 -      KdPrint((__DRIVER_NAME "     Requested MSS (%d) larger than allowed MSS (%d)\n", mss, xi->setting_max_offload));
   6.219 +      KdPrint((__DRIVER_NAME "     Requested MSS (%d) larger than allowed MSS (%d)\n", mss, xi->current_lso_ipv4));
   6.220        //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_FAILURE);
   6.221        //FUNCTION_EXIT();
   6.222        return TRUE;
   6.223      }
   6.224 +    #endif
   6.225    }
   6.226  
   6.227    if (ndis_lso)
   6.228 @@ -235,29 +263,25 @@ KdPrint((__DRIVER_NAME "     J total_len
   6.229        KdPrint((__DRIVER_NAME "     large send specified when tcp_length < mss\n"));
   6.230      }
   6.231    }
   6.232 -#endif
   6.233  /*
   6.234  * See io/netif.h. Must put (A) 1st request, then (B) optional extra_info, then
   6.235  * (C) rest of requests on the ring. Only (A) has csum flags.
   6.236  */
   6.237  
   6.238    /* (A) */
   6.239 -  KdPrint((__DRIVER_NAME "     AA\n"));
   6.240 -  KdPrint((__DRIVER_NAME "     AA XenNet_PutCbOnRing %d\n", min(PAGE_SIZE, remaining)));
   6.241    tx0 = XenNet_PutCbOnRing(xi, coalesce_buf, pi.header_length, gref);
   6.242    ASSERT(tx0); /* this will never happen */
   6.243    tx0->flags = flags;
   6.244    tx_length += pi.header_length;
   6.245  
   6.246 -  /* even though we haven't reported that we are capable of it, LSO demands that we calculate the IP Header checksum */
   6.247 -  if (ndis_lso)
   6.248 +  /* lso implies IpHeaderChecksum */
   6.249 +  if (ndis_lso || csum_info.Transmit.IpHeaderChecksum)
   6.250    {
   6.251      XenNet_SumIpHeader(coalesce_buf, pi.ip4_header_length);
   6.252    }
   6.253    txN = tx0;
   6.254  
   6.255    /* (B) */
   6.256 -  KdPrint((__DRIVER_NAME "     BB\n"));
   6.257    if (xen_gso)
   6.258    {
   6.259      ASSERT(flags & NETTXF_extra_info);
   6.260 @@ -276,7 +300,6 @@ KdPrint((__DRIVER_NAME "     J total_len
   6.261    ASSERT(xi->config_sg || !remaining);
   6.262    
   6.263    /* (C) - only if data is remaining */
   6.264 -  KdPrint((__DRIVER_NAME "     CC\n"));
   6.265    coalesce_buf = NULL;
   6.266    while (remaining > 0)
   6.267    {
   6.268 @@ -333,7 +356,6 @@ KdPrint((__DRIVER_NAME "     J total_len
   6.269      {
   6.270        if (remaining)
   6.271        {
   6.272 -        KdPrint((__DRIVER_NAME "     CC XenNet_PutCbOnRing %d\n", min(PAGE_SIZE, remaining)));
   6.273          txN = XenNet_PutCbOnRing(xi, coalesce_buf, min(PAGE_SIZE, remaining), gref);
   6.274          ASSERT(txN);
   6.275          coalesce_buf = NULL;
   6.276 @@ -379,13 +401,11 @@ KdPrint((__DRIVER_NAME "     J total_len
   6.277    ASSERT(!xi->tx_shadows[txN->id].nb);
   6.278    xi->tx_shadows[txN->id].nb = nb;
   6.279  
   6.280 -#if 0
   6.281    if (ndis_lso)
   6.282    {
   6.283      //KdPrint((__DRIVER_NAME "     TcpLargeSendPacketInfo = %d\n", pi.tcp_length));
   6.284 -    NDIS_PER_PACKET_INFO_FROM_PACKET(packet, TcpLargeSendPacketInfo) = UlongToPtr(tx_length - MAX_ETH_HEADER_LENGTH - pi.ip4_header_length - pi.tcp_header_length);
   6.285 +    NET_BUFFER_LIST_INFO(NB_NBL(nb), TcpOffloadBytesTransferred) = UlongToPtr(tx_length - MAX_ETH_HEADER_LENGTH - pi.ip4_header_length - pi.tcp_header_length);
   6.286    }
   6.287 -#endif
   6.288  
   6.289    xi->stat_tx_ok++;
   6.290  
   6.291 @@ -413,7 +433,6 @@ XenNet_SendQueuedPackets(struct xennet_i
   6.292    while (nb_entry != &xi->tx_waiting_pkt_list)
   6.293    {
   6.294      nb = CONTAINING_RECORD(nb_entry, NET_BUFFER, NB_LIST_ENTRY_FIELD);
   6.295 -    KdPrint((__DRIVER_NAME "     sending %p from %p\n", nb, NB_NBL(nb)));
   6.296      
   6.297      if (!XenNet_HWSendPacket(xi, nb))
   6.298      {
   6.299 @@ -442,7 +461,7 @@ XenNet_TxBufferGC(struct xennet_info *xi
   6.300    PNET_BUFFER nb;
   6.301    ULONG tx_packets = 0;
   6.302  
   6.303 -  FUNCTION_ENTER();
   6.304 +  //FUNCTION_ENTER();
   6.305  
   6.306    if (!xi->connected)
   6.307      return; /* a delayed DPC could let this come through... just do nothing */
   6.308 @@ -494,7 +513,7 @@ XenNet_TxBufferGC(struct xennet_info *xi
   6.309        if (shadow->nb)
   6.310        {
   6.311          PLIST_ENTRY nb_entry;
   6.312 -        KdPrint((__DRIVER_NAME "     nb %p complete\n"));
   6.313 +        //KdPrint((__DRIVER_NAME "     nb %p complete\n"));
   6.314          nb = shadow->nb;
   6.315          nb_entry = &NB_LIST_ENTRY(nb);
   6.316          InsertTailList(&nb_head, nb_entry);
   6.317 @@ -526,12 +545,10 @@ XenNet_TxBufferGC(struct xennet_info *xi
   6.318      nb = CONTAINING_RECORD(nb_entry, NET_BUFFER, NB_LIST_ENTRY_FIELD);
   6.319      nbl = NB_NBL(nb);
   6.320      NBL_REF(nbl)--;
   6.321 -    KdPrint((__DRIVER_NAME "     nb %p from %p complete, refcount = %d\n", nb, nbl, NBL_REF(nbl)));
   6.322      if (!NBL_REF(nbl))
   6.323      {
   6.324        nbl->Status = NDIS_STATUS_SUCCESS;
   6.325        NdisMSendNetBufferListsComplete(xi->adapter_handle, nbl, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
   6.326 -      KdPrint((__DRIVER_NAME "     NdisMSendNetBufferListsComplete\n"));
   6.327      }
   6.328      tx_packets++;
   6.329      nb_entry = RemoveHeadList(&nb_head);
   6.330 @@ -554,7 +571,7 @@ XenNet_TxBufferGC(struct xennet_info *xi
   6.331      xi->vectors.EvtChn_Notify(xi->vectors.context, xi->device_state->pdo_event_channel);
   6.332    }
   6.333  
   6.334 -  FUNCTION_EXIT();
   6.335 +  //FUNCTION_EXIT();
   6.336  }
   6.337  
   6.338  // called at <= DISPATCH_LEVEL
   6.339 @@ -571,7 +588,7 @@ XenNet_SendNetBufferLists(
   6.340    PNET_BUFFER_LIST curr_nbl;
   6.341  
   6.342    UNREFERENCED_PARAMETER(port_number);
   6.343 -  FUNCTION_ENTER();
   6.344 +  //FUNCTION_ENTER();
   6.345  
   6.346    if (xi->inactive)
   6.347    {
   6.348 @@ -606,7 +623,7 @@ XenNet_SendNetBufferLists(
   6.349  
   6.350    KeReleaseSpinLock(&xi->tx_lock, old_irql);
   6.351    
   6.352 -  FUNCTION_EXIT();
   6.353 +  //FUNCTION_EXIT();
   6.354  }
   6.355  
   6.356  VOID