win-pvdrivers

changeset 217:f315522a2a3e

This won't work.
author James Harper <james.harper@bendigoit.com.au>
date Fri Mar 21 17:51:32 2008 +1100 (2008-03-21)
parents 6f57a4124ab7
children c33404027885
files common.inc xennet/xennet_oid.c xennet/xennet_rx.c xennet/xennet_tx.c
line diff
     1.1 --- a/common.inc	Sat Mar 15 00:44:03 2008 +1100
     1.2 +++ b/common.inc	Fri Mar 21 17:51:32 2008 +1100
     1.3 @@ -1,4 +1,4 @@
     1.4 -VERSION=0.8.5.9
     1.5 +VERSION=0.8.5.43
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7  KMDF_VERSION=1
     1.8  !IF $(_NT_TOOLS_VERSION) > 0x700
     2.1 --- a/xennet/xennet_oid.c	Sat Mar 15 00:44:03 2008 +1100
     2.2 +++ b/xennet/xennet_oid.c	Fri Mar 21 17:51:32 2008 +1100
     2.3 @@ -233,41 +233,62 @@ XenNet_QueryInformation(
     2.4          status = NDIS_STATUS_NOT_SUPPORTED;
     2.5          break;
     2.6        }
     2.7 -      ntoh->OffsetFirstTask = ntoh->Size;
     2.8 -
     2.9 -      /* fill in first nto */
    2.10 -      nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(ntoh) + ntoh->OffsetFirstTask);
    2.11 -      nto->Version = NDIS_TASK_OFFLOAD_VERSION;
    2.12 -      nto->Size = sizeof(NDIS_TASK_OFFLOAD);
    2.13 -      nto->Task = TcpIpChecksumNdisTask;
    2.14 -      nto->TaskBufferLength = sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
    2.15 +      ntoh->OffsetFirstTask = 0; 
    2.16 +      nto = NULL;
    2.17  
    2.18 -      /* fill in checksum offload struct */
    2.19 -      nttic = (PNDIS_TASK_TCP_IP_CHECKSUM)nto->TaskBuffer;
    2.20 -      nttic->V4Transmit.IpChecksum = 0;
    2.21 -      nttic->V4Transmit.IpOptionsSupported = 0;
    2.22 -      nttic->V4Transmit.TcpChecksum = 1;
    2.23 -      nttic->V4Transmit.TcpOptionsSupported = 1;
    2.24 -      nttic->V4Transmit.UdpChecksum = 1;
    2.25 -      nttic->V4Receive.IpChecksum = 0;
    2.26 -      nttic->V4Receive.IpOptionsSupported = 0;
    2.27 -      nttic->V4Receive.TcpChecksum = 1;
    2.28 -      nttic->V4Receive.TcpOptionsSupported = 1;
    2.29 -      nttic->V4Receive.UdpChecksum = 1;
    2.30 -      nttic->V6Transmit.IpOptionsSupported = 0;
    2.31 -      nttic->V6Transmit.TcpOptionsSupported = 0;
    2.32 -      nttic->V6Transmit.TcpChecksum = 0;
    2.33 -      nttic->V6Transmit.UdpChecksum = 0;
    2.34 -      nttic->V6Receive.IpOptionsSupported = 0;
    2.35 -      nttic->V6Receive.TcpOptionsSupported = 0;
    2.36 -      nttic->V6Receive.TcpChecksum = 0;
    2.37 -      nttic->V6Receive.UdpChecksum = 0;
    2.38 +      if (xi->config_csum)
    2.39 +      {
    2.40 +        if (ntoh->OffsetFirstTask == 0)
    2.41 +        {
    2.42 +          ntoh->OffsetFirstTask = ntoh->Size;
    2.43 +          nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(ntoh) + ntoh->OffsetFirstTask);
    2.44 +        }
    2.45 +        else
    2.46 +        {
    2.47 +          nto->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
    2.48 +            + nto->TaskBufferLength;
    2.49 +          nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(nto) + nto->OffsetNextTask);
    2.50 +        }
    2.51 +        /* fill in first nto */
    2.52 +        nto->Version = NDIS_TASK_OFFLOAD_VERSION;
    2.53 +        nto->Size = sizeof(NDIS_TASK_OFFLOAD);
    2.54 +        nto->Task = TcpIpChecksumNdisTask;
    2.55 +        nto->TaskBufferLength = sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
    2.56  
    2.57 +        /* fill in checksum offload struct */
    2.58 +        nttic = (PNDIS_TASK_TCP_IP_CHECKSUM)nto->TaskBuffer;
    2.59 +        nttic->V4Transmit.IpChecksum = 0;
    2.60 +        nttic->V4Transmit.IpOptionsSupported = 0;
    2.61 +        nttic->V4Transmit.TcpChecksum = 1;
    2.62 +        nttic->V4Transmit.TcpOptionsSupported = 1;
    2.63 +        nttic->V4Transmit.UdpChecksum = 1;
    2.64 +        nttic->V4Receive.IpChecksum = 1;
    2.65 +        nttic->V4Receive.IpOptionsSupported = 1;
    2.66 +        nttic->V4Receive.TcpChecksum = 1;
    2.67 +        nttic->V4Receive.TcpOptionsSupported = 1;
    2.68 +        nttic->V4Receive.UdpChecksum = 1;
    2.69 +        nttic->V6Transmit.IpOptionsSupported = 0;
    2.70 +        nttic->V6Transmit.TcpOptionsSupported = 0;
    2.71 +        nttic->V6Transmit.TcpChecksum = 0;
    2.72 +        nttic->V6Transmit.UdpChecksum = 0;
    2.73 +        nttic->V6Receive.IpOptionsSupported = 0;
    2.74 +        nttic->V6Receive.TcpOptionsSupported = 0;
    2.75 +        nttic->V6Receive.TcpChecksum = 0;
    2.76 +        nttic->V6Receive.UdpChecksum = 0;
    2.77 +      }
    2.78        if (xi->config_gso)
    2.79        {
    2.80 -        /* offset from start of current NTO to start of next NTO */
    2.81 -        nto->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
    2.82 -          + nto->TaskBufferLength;
    2.83 +        if (ntoh->OffsetFirstTask == 0)
    2.84 +        {
    2.85 +          ntoh->OffsetFirstTask = ntoh->Size;
    2.86 +          nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(ntoh) + ntoh->OffsetFirstTask);
    2.87 +        }
    2.88 +        else
    2.89 +        {
    2.90 +          nto->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
    2.91 +            + nto->TaskBufferLength;
    2.92 +          nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(nto) + nto->OffsetNextTask);
    2.93 +        }
    2.94    
    2.95          /* fill in second nto */
    2.96          nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(nto) + nto->OffsetNextTask);
    2.97 @@ -285,7 +306,8 @@ XenNet_QueryInformation(
    2.98          nttls->IpOptions = TRUE;
    2.99        }
   2.100  
   2.101 -      nto->OffsetNextTask = 0; /* last one */
   2.102 +      if (!nto)
   2.103 +        nto->OffsetNextTask = 0; /* last one */
   2.104  
   2.105        used_temp_buffer = FALSE;
   2.106        break;
     3.1 --- a/xennet/xennet_rx.c	Sat Mar 15 00:44:03 2008 +1100
     3.2 +++ b/xennet/xennet_rx.c	Fri Mar 21 17:51:32 2008 +1100
     3.3 @@ -161,7 +161,6 @@ XenNet_SplitRxPacket(
     3.4  
     3.5    KdPrint((__DRIVER_NAME "     mss = %d\n", mss));
     3.6  
     3.7 -/*
     3.8    while (remaining)
     3.9    {
    3.10      // take the buffers off of the current packet
    3.11 @@ -181,12 +180,238 @@ XenNet_SplitRxPacket(
    3.12      // append the remaining data buffers
    3.13      // increment the packet count
    3.14    }
    3.15 -*/  
    3.16 +
    3.17    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    3.18  
    3.19    return;
    3.20  }
    3.21  
    3.22 +#define __NET_USHORT_BYTE_0(x) ((USHORT)(x & 0xFF))
    3.23 +#define __NET_USHORT_BYTE_1(x) ((USHORT)((PUCHAR)&x)[1] & 0xFF)
    3.24 +#define NET_USHORT(x) ((__NET_USHORT_BYTE_0(x) << 8) | __NET_USHORT_BYTE_1(x))
    3.25 +
    3.26 +static VOID
    3.27 +XenNet_SplitLargePackets(
    3.28 +  PNDIS_PACKET *packets,
    3.29 +  ULONG packet_count,
    3.30 +  PULONG new_packets,
    3.31 +  USHORT ip4_length,
    3.32 +  USHORT ip4_header_length,
    3.33 +  USHORT tcp_header_length
    3.34 +)
    3.35 +{
    3.36 +  PUCHAR header;
    3.37 +  PNDIS_PACKET first_packet;
    3.38 +  PNDIS_PACKET curr_packet;
    3.39 +
    3.40 +  new_packets = 0;
    3.41 +
    3.42 +  header = buffer;
    3.43 +  remaining = ip4_length - ip4_header_length - tcp_header_length;
    3.44 +  // save psh status of packet
    3.45 +  while (remaining)
    3.46 +  {
    3.47 +    *((PUSHORT)&buffer[XN_HDR_SIZE + 2]) = NET_USHORT(mss);
    3.48 +    tcp_length = min(remaining, mss);
    3.49 +    remaining -= tcp_length;
    3.50 +
    3.51 +      // clear psh of old packet
    3.52 +
    3.53 +    NdisAllocatePacket(&status, &packets[packet_count + 1], xi->packet_pool);
    3.54 +    ASSERT(status == NDIS_STATUS_SUCCESS);
    3.55 +    NDIS_SET_PACKET_HEADER_SIZE(packets[packet_count + 1], XN_HDR_SIZE);
    3.56 +
    3.57 +    new_buffer_mdl = get_page_from_freelist(xi);
    3.58 +    new_buffer = MmGetMdlVirtualAddress(new_buffer_mdl);
    3.59 +    memcpy(new_buffer, buffer, XN_HDR_SIZE + ip4_header_length + tcp_header_length);
    3.60 +    *((PUSHORT)&new_header[XN_HDR_SIZE + 2]) = NET_USHORT(tcp_length);
    3.61 +    // fix tcp sequence of new packet
    3.62 +    new_remaining = tcp_length;
    3.63 +    while (new_remaining > 0)
    3.64 +    {
    3.65 +         
    3.66 +      if (buffer_offset != 0)
    3.67 +      {
    3.68 +        new_buffer = 
    3.69 +        // allocate a new buffer
    3.70 +        // copy remaining data to new buffer
    3.71 +        // set length of current buffer
    3.72 +        // set length of new buffer
    3.73 +      }
    3.74 +
    3.75 +// I was up to here...
    3.76 +      NdisUnchainBufferAtBack(packets[packet_count], &mdl);
    3.77 +      NdisChainBufferAtFront(packets[packet_count + 1], mdl);
    3.78 +      NdisChainBufferAtFront(packets[packet_count + 1], new_header_mdl);
    3.79 +      
    3.80 +      
    3.81 +      // copy all buffers to new packet
    3.82 +      packet_count++;
    3.83 +    }
    3.84 +    // restore psh status to last packet
    3.85 +}
    3.86 +
    3.87 +/*
    3.88 + Windows appears to insist that the checksum on received packets is correct, and won't
    3.89 + believe us when we lie about it, which happens when the packet is generated on the
    3.90 + same bridge in Dom0. Doh!
    3.91 + This is only for TCP and UDP packets. IP checksums appear to be correct anyways.
    3.92 +*/
    3.93 +static VOID
    3.94 +XenNet_SumData(
    3.95 +  PNDIS_PACKET packet
    3.96 +)
    3.97 +{
    3.98 +  USHORT i;
    3.99 +  PUCHAR buffer;
   3.100 +  PMDL mdl;
   3.101 +  UINT total_length;
   3.102 +  UINT buffer_length;
   3.103 +  ULONG csum, pre_csum;
   3.104 +  PUSHORT csum_ptr;
   3.105 +  UCHAR ip_version;
   3.106 +  USHORT ip4_header_length;
   3.107 +  USHORT ip4_length;
   3.108 +  USHORT tcp_header_length;
   3.109 +  USHORT tcp_length;
   3.110 +  USHORT buffer_offset;
   3.111 +  USHORT mss;
   3.112 +  PNDIS_PACKET packet;
   3.113 +
   3.114 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.115 +
   3.116 +  mss = PtrToUlong(NDIS_PER_PACKET_INFO_FROM_PACKET(packets[packet_count], TcpLargeSendPacketInfo);
   3.117 +  NdisGetFirstBufferFromPacketSafe(packet, &mdl, &buffer, &buffer_length, &total_length, NormalPagePriority);
   3.118 +  if (mdl == NULL)
   3.119 +  {
   3.120 +    KdPrint((__DRIVER_NAME "     Cannot get first buffer\n"));
   3.121 +    return;
   3.122 +  }
   3.123 +
   3.124 +  if (buffer_length < XN_HDR_SIZE + 20 + 20) // minimum size of ETH + IP + TCP header
   3.125 +  {
   3.126 +    KdPrint((__DRIVER_NAME "     %d is not enough data for the first buffer\n", buffer_length));
   3.127 +    return;
   3.128 +  }
   3.129 +  
   3.130 +  switch (NET_USHORT(buffer[12])) // L2 protocol field
   3.131 +  {
   3.132 +  case 0x0800:
   3.133 +    ip_version = (buffer[XN_HDR_SIZE + 0] & 0xF0) >> 4;
   3.134 +    if (ip_version != 4)
   3.135 +    {
   3.136 +      KdPrint((__DRIVER_NAME "     ip_version = %d\n", ip_version));
   3.137 +      return;
   3.138 +    }
   3.139 +    ip4_header_length = (buffer[XN_HDR_SIZE + 0] & 0x0F) << 2;
   3.140 +    if (buffer_length < (ULONG)(ip4_header_length + 20))
   3.141 +    {
   3.142 +      KdPrint((__DRIVER_NAME "     first packet is only %d long, must be >= %d\n", XN_HDR_SIZE + buffer_length, (ULONG)(XN_HDR_SIZE + ip4_header_length + 20)));
   3.143 +      return;
   3.144 +    }
   3.145 +    break;
   3.146 +  default:
   3.147 +    KdPrint((__DRIVER_NAME "     Not IP\n"));
   3.148 +    return;
   3.149 +  }
   3.150 +  switch (buffer[XN_HDR_SIZE + 9])
   3.151 +  {
   3.152 +  case 6:  // TCP
   3.153 +  case 17: // UDP
   3.154 +    break;
   3.155 +  default:
   3.156 +    KdPrint((__DRIVER_NAME "     Not TCP or UDP\n"));
   3.157 +    return;
   3.158 +  }
   3.159 +  ip4_length = NET_USHORT(buffer[XN_HDR_SIZE + 2]);
   3.160 +  tcp_header_length = (buffer[XN_HDR_SIZE + ip4_header_length + 12] & 0xf0) >> 2;
   3.161 +  csum_ptr = (USHORT *)&buffer[XN_HDR_SIZE + ip4_header_length + 16];
   3.162 +  *csum_ptr = 0;
   3.163 +
   3.164 +KdPrint((__DRIVER_NAME "     buffer_length = %d, total_length = %d, ip4_length = %d, ip4_header_length = %d, tcp_header_length = %d\n", buffer_length, total_length, ip4_length, ip4_header_length, tcp_header_length));
   3.165 +
   3.166 +  ASSERT((USHORT)(ip4_length + XN_HDR_SIZE) == total_length);
   3.167 +
   3.168 +  remaining = ip4_length - ip4_header_length - tcp_header_length;
   3.169 +  if (mss && remaining > mss)
   3.170 +  {
   3.171 +    ASSERT(mss <= PAGE_SIZE); // maybe fix this one day, but its a good assumption for now
   3.172 +    SplitLargePackets(packets, current_packet, &new_packets);
   3.173 +  }
   3.174 +  
   3.175 +  pre_csum = 0;
   3.176 +  pre_csum += NET_USHORT(buffer[XN_HDR_SIZE + 12]) + NET_USHORT(buffer[XN_HDR_SIZE + 14]);
   3.177 +  pre_csum += NET_USHORT(buffer[XN_HDR_SIZE + 16]) + NET_USHORT(buffer[XN_HDR_SIZE + 18]);
   3.178 +  pre_csum += ((USHORT)buffer[XN_HDR_SIZE + 9]);
   3.179 +
   3.180 +  remaining = ip4_length - ip4_header_length;
   3.181 +
   3.182 +  while (remaining > 0)
   3.183 +  {
   3.184 +    if (mss == 0)
   3.185 +      tcp_length = remaining;
   3.186 +    else
   3.187 +      tcp_length = min(remaining, mss);
   3.188 +    remaining -= tcp_length;
   3.189 +
   3.190 +    csum = pre_csum + tcp_length;
   3.191 +    for (buffer_offset = i = XN_HDR_SIZE + ip4_header_length; i < tcp_length - 1; i += 2, buffer_offset += 2)
   3.192 +    {
   3.193 +      if (buffer_offset == buffer_length - 1) // deal with a buffer ending on an odd byte boundary
   3.194 +      {
   3.195 +        csum += (USHORT)buffer[buffer_offset] << 8;
   3.196 +        NdisGetNextBuffer(mdl, &mdl);
   3.197 +        if (mdl == NULL)
   3.198 +        {
   3.199 +          KdPrint((__DRIVER_NAME "     Ran out of buffers\n"));
   3.200 +          return;
   3.201 +        }
   3.202 +        NdisQueryBufferSafe(mdl, &buffer, &buffer_length, NormalPagePriority);
   3.203 +        KdPrint((__DRIVER_NAME "     New buffer - unaligned...\n"));
   3.204 +        csum += ((USHORT)buffer[0]);
   3.205 +        buffer_offset = -1;
   3.206 +      }
   3.207 +      else
   3.208 +      {
   3.209 +        if (buffer_offset == buffer_length)
   3.210 +        {
   3.211 +          KdPrint((__DRIVER_NAME "     New buffer - aligned...\n"));
   3.212 +          NdisGetNextBuffer(mdl, &mdl);
   3.213 +          if (mdl == NULL)
   3.214 +          {
   3.215 +            KdPrint((__DRIVER_NAME "     Ran out of buffers\n"));
   3.216 +            return;
   3.217 +          }
   3.218 +          NdisQueryBufferSafe(mdl, &buffer, &buffer_length, NormalPagePriority);
   3.219 +          buffer_offset = 0;
   3.220 +        }
   3.221 +        csum += NET_USHORT(buffer[buffer_offset]);
   3.222 +//KdPrint((__DRIVER_NAME "     %04X\n", NET_USHORT(buffer[buffer_offset])));
   3.223 +      }
   3.224 +    }
   3.225 +    if (i != ip4_length) // last odd byte
   3.226 +    {
   3.227 +//KdPrint((__DRIVER_NAME "    *%04X\n", (USHORT)buffer[buffer_offset] << 8));
   3.228 +      csum += ((USHORT)buffer[buffer_offset] << 8);
   3.229 +    }
   3.230 +    while (csum & 0xFFFF0000)
   3.231 +      csum = (csum & 0xFFFF) + (csum >> 16);
   3.232 +    *csum_ptr = (USHORT)~NET_USHORT(csum);
   3.233 +
   3.234 +    if (remaining != 0)
   3.235 +    {
   3.236 +      // create a new packet
   3.237 +      // copy the header to a new buffer
   3.238 +      // if we are not at the start of the current buffer, copy the remaining data from the current buffer into a new buffer
   3.239 +      
   3.240 +    }
   3.241 +  
   3.242 +    KdPrint((__DRIVER_NAME "     csum = %04x\n", *csum_ptr));
   3.243 +  }
   3.244 +
   3.245 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.246 +}
   3.247 +
   3.248  // Called at DISPATCH_LEVEL
   3.249  NDIS_STATUS
   3.250  XenNet_RxBufferCheck(struct xennet_info *xi)
   3.251 @@ -195,7 +420,6 @@ XenNet_RxBufferCheck(struct xennet_info 
   3.252    PNDIS_PACKET packets[NET_RX_RING_SIZE];
   3.253    ULONG packet_count;
   3.254    PMDL mdl;
   3.255 -  PMDL first_mdl = NULL;
   3.256    int moretodo;
   3.257    struct netif_rx_response *rxrsp = NULL;
   3.258    struct netif_extra_info *ei;
   3.259 @@ -204,7 +428,7 @@ XenNet_RxBufferCheck(struct xennet_info 
   3.260    USHORT id;
   3.261    PNDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
   3.262    USHORT total_packet_length = 0;
   3.263 -  USHORT first_buffer_length = 0;
   3.264 +  BOOLEAN csum_calc_required;
   3.265    int cycles = 0;
   3.266  #if defined(XEN_PROFILE)
   3.267    LARGE_INTEGER tsc, tsc2, dummy;
   3.268 @@ -221,20 +445,20 @@ XenNet_RxBufferCheck(struct xennet_info 
   3.269    KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
   3.270  
   3.271    packet_count = 0;
   3.272 +  csum_calc_required = FALSE;
   3.273    if (xi->rx_current_packet)
   3.274    {
   3.275 -    packets[0] = xi->rx_current_packet;
   3.276 +    packets[packet_count] = xi->rx_current_packet;
   3.277      xi->rx_current_packet = NULL;
   3.278 -    first_mdl = xi->rx_first_mdl;
   3.279      more_frags = NETRXF_more_data;
   3.280 -    first_buffer_length = xi->rx_first_buffer_length;
   3.281    }
   3.282    do {
   3.283      ASSERT(cycles++ < 256);
   3.284      prod = xi->rx.sring->rsp_prod;
   3.285      KeMemoryBarrier(); /* Ensure we see responses up to 'rp'. */
   3.286  
   3.287 -    for (cons = xi->rx.rsp_cons; cons != prod; cons++) {
   3.288 +    for (cons = xi->rx.rsp_cons; cons != prod; cons++)
   3.289 +    {
   3.290        ASSERT(cycles++ < 256);
   3.291        id = (USHORT)(cons & (NET_RX_RING_SIZE - 1));
   3.292        mdl = xi->rx_buffers[id];
   3.293 @@ -242,18 +466,18 @@ XenNet_RxBufferCheck(struct xennet_info 
   3.294        xi->rx_id_free++;
   3.295        if (xi->rx_extra_info)
   3.296        {
   3.297 -//KdPrint((__DRIVER_NAME "     RX extra info detected\n"));
   3.298 +KdPrint((__DRIVER_NAME "     RX extra info packet detected\n"));
   3.299          put_page_on_freelist(xi, mdl);
   3.300          ei = (struct netif_extra_info *)RING_GET_RESPONSE(&xi->rx, cons);
   3.301          xi->rx_extra_info = ei->flags & XEN_NETIF_EXTRA_FLAG_MORE;
   3.302          switch (ei->type)
   3.303          {
   3.304          case XEN_NETIF_EXTRA_TYPE_GSO:
   3.305 -//KdPrint((__DRIVER_NAME "     GSO detected - size = %d\n", ei->u.gso.size));
   3.306 +KdPrint((__DRIVER_NAME "     GSO detected - size = %d\n", ei->u.gso.size));
   3.307            switch (ei->u.gso.type)
   3.308            {
   3.309            case XEN_NETIF_GSO_TYPE_TCPV4:
   3.310 -//KdPrint((__DRIVER_NAME "     GSO_TYPE_TCPV4 detected\n"));
   3.311 +KdPrint((__DRIVER_NAME "     GSO_TYPE_TCPV4 detected\n"));
   3.312              NDIS_PER_PACKET_INFO_FROM_PACKET(packets[packet_count], TcpLargeSendPacketInfo) = (PVOID)(xen_ulong_t)(ei->u.gso.size);
   3.313              break;
   3.314            default:
   3.315 @@ -280,53 +504,58 @@ XenNet_RxBufferCheck(struct xennet_info 
   3.316          ASSERT(rxrsp->id == id);
   3.317          if (!more_frags) // handling the packet's 1st buffer
   3.318          {
   3.319 -          first_buffer_length = total_packet_length = rxrsp->status;
   3.320 -          first_mdl = mdl;
   3.321            NdisAllocatePacket(&status, &packets[packet_count], xi->packet_pool);
   3.322            ASSERT(status == NDIS_STATUS_SUCCESS);
   3.323            NDIS_SET_PACKET_HEADER_SIZE(packets[packet_count], XN_HDR_SIZE);
   3.324            NDIS_PER_PACKET_INFO_FROM_PACKET(packets[packet_count], TcpLargeSendPacketInfo) = 0;
   3.325 -          if (rxrsp->flags & (NETRXF_csum_blank|NETRXF_data_validated)) // and we are enabled for offload...
   3.326 +          total_packet_length = 0;
   3.327 +          if (rxrsp->flags & (NETRXF_csum_blank|NETRXF_data_validated) && xi->config_csum) // and we are enabled for offload...
   3.328            {
   3.329 +//KdPrint((__DRIVER_NAME "     RX csum blank = %d, validated = %d\n", !!(rxrsp->flags & NETRXF_csum_blank), !!(rxrsp->flags & NETRXF_data_validated)));
   3.330 +            if (rxrsp->flags & NETRXF_csum_blank)
   3.331 +              csum_calc_required = TRUE;
   3.332              csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(packets[packet_count], TcpIpChecksumPacketInfo);
   3.333              csum_info->Receive.NdisPacketTcpChecksumSucceeded = 1;
   3.334 -            csum_info->Receive.NdisPacketUdpChecksumSucceeded = 1;
   3.335 +            csum_info->Receive.NdisPacketUdpChecksumSucceeded = 0;
   3.336              csum_info->Receive.NdisPacketIpChecksumSucceeded = 1;
   3.337  #if defined(XEN_PROFILE)
   3.338              ProfCount_RxPacketsCsumOffload++;
   3.339  #endif
   3.340 +//KdPrint((__DRIVER_NAME "     RX csum offload TcpFailed = %d, UdpFailed = %d\n", csum_info->Receive.NdisPacketTcpChecksumFailed, csum_info->Receive.NdisPacketUdpChecksumFailed));
   3.341            }
   3.342          }
   3.343 -        else
   3.344 -        {
   3.345 -          NdisAdjustBufferLength(mdl, rxrsp->status);
   3.346 -          NdisChainBufferAtBack(packets[packet_count], mdl);
   3.347 -          first_buffer_length = first_buffer_length  - (USHORT)rxrsp->status;
   3.348 -        }
   3.349 +        total_packet_length = total_packet_length  + rxrsp->status;
   3.350 +        NdisAdjustBufferLength(mdl, rxrsp->status);
   3.351 +        NdisChainBufferAtBack(packets[packet_count], mdl);
   3.352          
   3.353          xi->rx_extra_info = rxrsp->flags & NETRXF_extra_info;
   3.354          more_frags = rxrsp->flags & NETRXF_more_data;
   3.355        }
   3.356  
   3.357 +if (more_frags)
   3.358 +  KdPrint((__DRIVER_NAME "     more frags\n"));
   3.359        /* Packet done, add it to the list */
   3.360        if (!more_frags && !xi->rx_extra_info)
   3.361        {
   3.362 -        NdisAdjustBufferLength(first_mdl, first_buffer_length);
   3.363 -        NdisChainBufferAtFront(packets[packet_count], first_mdl);
   3.364 -
   3.365 -//if (PtrToUlong(NDIS_PER_PACKET_INFO_FROM_PACKET(packets[packet_count], TcpLargeSendPacketInfo)))
   3.366 -//  KdPrint((__DRIVER_NAME "     first_buffer_length = %d, total length = %d\n", first_buffer_length, total_packet_length));
   3.367 +if (PtrToUlong(NDIS_PER_PACKET_INFO_FROM_PACKET(packets[packet_count], TcpLargeSendPacketInfo)))
   3.368 +  KdPrint((__DRIVER_NAME "     total length = %d, mss = %d\n", total_packet_length, PtrToUlong(NDIS_PER_PACKET_INFO_FROM_PACKET(packets[packet_count], TcpLargeSendPacketInfo))));
   3.369  #if defined(XEN_PROFILE)
   3.370          ProfCount_RxPacketsTotal++;
   3.371  #endif
   3.372          xi->stat_rx_ok++;
   3.373          NDIS_SET_PACKET_STATUS(packets[packet_count], NDIS_STATUS_SUCCESS);
   3.374  
   3.375 +/*
   3.376          if (total_packet_length > xi->config_mtu + XN_HDR_SIZE)
   3.377          {
   3.378            KdPrint((__DRIVER_NAME "     total_packet_length %d, config_mtu = %d\n", total_packet_length, xi->config_mtu));
   3.379            XenNet_SplitRxPacket(packets, &packet_count, total_packet_length);
   3.380          }
   3.381 +        else */ if (csum_calc_required)
   3.382 +        {
   3.383 +          XenNet_SumData(packets[packet_count]);
   3.384 +          csum_calc_required = FALSE;
   3.385 +        }
   3.386  
   3.387          packet_count++;
   3.388        }
   3.389 @@ -341,9 +570,8 @@ XenNet_RxBufferCheck(struct xennet_info 
   3.390  
   3.391    if (more_frags)
   3.392    {
   3.393 +KdPrint((__DRIVER_NAME "     leftover frags\n"));
   3.394      xi->rx_current_packet = packets[packet_count];
   3.395 -    xi->rx_first_mdl = first_mdl;
   3.396 -    xi->rx_first_buffer_length = first_buffer_length;
   3.397    }
   3.398  
   3.399    KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
     4.1 --- a/xennet/xennet_tx.c	Sat Mar 15 00:44:03 2008 +1100
     4.2 +++ b/xennet/xennet_tx.c	Fri Mar 21 17:51:32 2008 +1100
     4.3 @@ -71,9 +71,9 @@ put_gref_on_freelist(struct xennet_info 
     4.4  #define SWAP_USHORT(x) (USHORT)((((x & 0xFF) << 8)|((x >> 8) & 0xFF)))
     4.5  
     4.6  /*
     4.7 - * Windows assumes that if we can do large send offload then we can
     4.8 - * do IP header csum offload, so we have to fake it!
     4.9 - */
    4.10 + Windows assumes that if we can do large send offload then we can
    4.11 + do IP header csum offload, so we have to fake it!
    4.12 +*/
    4.13  VOID
    4.14  XenNet_SumHeader(
    4.15   PMDL mdl /* first buffer of the packet - containing the header */